1f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu/************************************************************************** 2f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 3f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com> 5f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2010-2011 LunarG, Inc. 6f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * All Rights Reserved. 7f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 8f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a 9f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * copy of this software and associated documentation files (the 10f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * "Software"), to deal in the Software without restriction, including 11f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * without limitation the rights to use, copy, modify, merge, publish, 12f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * distribute, sub license, and/or sell copies of the Software, and to 13f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * permit persons to whom the Software is furnished to do so, subject to 14f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * the following conditions: 15f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 16f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * The above copyright notice and this permission notice (including the 17f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * next paragraph) shall be included in all copies or substantial portions 18f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * of the Software. 19f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 20f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * DEALINGS IN THE SOFTWARE. 27f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 28f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu **************************************************************************/ 29f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu 30f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu 316052af172f0241e6678cd16efac0a0f14f40146cBrian Paul/** 326052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * Functions for choosing and opening/loading device drivers. 336052af172f0241e6678cd16efac0a0f14f40146cBrian Paul */ 346052af172f0241e6678cd16efac0a0f14f40146cBrian Paul 356052af172f0241e6678cd16efac0a0f14f40146cBrian Paul 36adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <assert.h> 3711a261ef4f1d4100c46f73ad51e7e4ed57cc1b5eBrian Paul#include <string.h> 38adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <stdio.h> 390c8908c411c434eda318b41b4f2a370a1e794831Brian Paul#include <stdlib.h> 401e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu 411e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu#include "eglstring.h" 42e084fe54f93c9d51df99812b76d3299b0cff57a3Brian Paul#include "egldefines.h" 43adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldisplay.h" 44adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldriver.h" 45b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul#include "egllog.h" 46f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu#include "eglmutex.h" 47adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul 486f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX) 496b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul#include <dlfcn.h> 50b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu#include <sys/types.h> 51b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu#include <dirent.h> 525d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu#include <unistd.h> 53b870bf79b5387f26668285f44ccbf5812ad62e10Jakob Bornecrantz#endif 54adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul 555541988578054345ca70b7ed7972710396e61b44Chia-I Wu 56f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wutypedef struct _egl_module { 57f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu char *Path; 58c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLMain_t BuiltIn; 59f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu void *Handle; 60f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDriver *Driver; 61f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} _EGLModule; 62f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 63f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGL_DECLARE_MUTEX(_eglModuleMutex); 64f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLArray *_eglModules; 65f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 66c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wuconst struct { 67c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu const char *name; 68c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLMain_t main; 69c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu} _eglBuiltInDrivers[] = { 70a8b6b6555c7d6a02a3d095c72ebbdc218bc45cd3Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_GALLIUM 71a8b6b6555c7d6a02a3d095c72ebbdc218bc45cd3Chia-I Wu { "egl_gallium", _eglBuiltInDriverGALLIUM }, 72a8b6b6555c7d6a02a3d095c72ebbdc218bc45cd3Chia-I Wu#endif 73c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_DRI2 74c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu { "egl_dri2", _eglBuiltInDriverDRI2 }, 75c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#endif 76c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_GLX 77c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu { "egl_glx", _eglBuiltInDriverGLX }, 78c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#endif 79c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu { NULL, NULL } 80c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu}; 81f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 82a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul/** 83a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul * Wrappers for dlopen/dlclose() 84a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul */ 856f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_WINDOWS) 86a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul 875541988578054345ca70b7ed7972710396e61b44Chia-I Wu 885541988578054345ca70b7ed7972710396e61b44Chia-I Wutypedef HMODULE lib_handle; 895541988578054345ca70b7ed7972710396e61b44Chia-I Wu 905541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic HMODULE 915541988578054345ca70b7ed7972710396e61b44Chia-I Wuopen_library(const char *filename) 925541988578054345ca70b7ed7972710396e61b44Chia-I Wu{ 935541988578054345ca70b7ed7972710396e61b44Chia-I Wu return LoadLibrary(filename); 945541988578054345ca70b7ed7972710396e61b44Chia-I Wu} 955541988578054345ca70b7ed7972710396e61b44Chia-I Wu 965541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic void 975541988578054345ca70b7ed7972710396e61b44Chia-I Wuclose_library(HMODULE lib) 985541988578054345ca70b7ed7972710396e61b44Chia-I Wu{ 995541988578054345ca70b7ed7972710396e61b44Chia-I Wu FreeLibrary(lib); 1005541988578054345ca70b7ed7972710396e61b44Chia-I Wu} 1015541988578054345ca70b7ed7972710396e61b44Chia-I Wu 102ab0d13dd60c707f2c414fa9fe8e489a9e24a8aeeJonathan White 103b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wustatic const char * 104b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wulibrary_suffix(void) 105b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 1065d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return ".dll"; 10721b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu} 10821b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu 10921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu 1106f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#elif defined(_EGL_OS_UNIX) 111a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul 112a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul 1135541988578054345ca70b7ed7972710396e61b44Chia-I Wutypedef void * lib_handle; 1145541988578054345ca70b7ed7972710396e61b44Chia-I Wu 1155541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic void * 1165541988578054345ca70b7ed7972710396e61b44Chia-I Wuopen_library(const char *filename) 1175541988578054345ca70b7ed7972710396e61b44Chia-I Wu{ 1185541988578054345ca70b7ed7972710396e61b44Chia-I Wu return dlopen(filename, RTLD_LAZY); 1195541988578054345ca70b7ed7972710396e61b44Chia-I Wu} 1205541988578054345ca70b7ed7972710396e61b44Chia-I Wu 1215541988578054345ca70b7ed7972710396e61b44Chia-I Wustatic void 1225541988578054345ca70b7ed7972710396e61b44Chia-I Wuclose_library(void *lib) 1235541988578054345ca70b7ed7972710396e61b44Chia-I Wu{ 1245541988578054345ca70b7ed7972710396e61b44Chia-I Wu dlclose(lib); 1255541988578054345ca70b7ed7972710396e61b44Chia-I Wu} 1265541988578054345ca70b7ed7972710396e61b44Chia-I Wu 127b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 128b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wustatic const char * 129b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wulibrary_suffix(void) 130b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 1315d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return ".so"; 13221b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu} 13321b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu 13421b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu 135a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul#endif 136a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul 1370eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 138adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul/** 1390eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu * Open the named driver and find its bootstrap function: _eglMain(). 140adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul */ 1410eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wustatic _EGLMain_t 142b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu_eglOpenLibrary(const char *driverPath, lib_handle *handle) 143adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul{ 144a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul lib_handle lib; 1455541988578054345ca70b7ed7972710396e61b44Chia-I Wu _EGLMain_t mainFunc = NULL; 1465541988578054345ca70b7ed7972710396e61b44Chia-I Wu const char *error = "unknown error"; 147adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul 148b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu assert(driverPath); 1496052af172f0241e6678cd16efac0a0f14f40146cBrian Paul 150b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath); 151b1f156f0ecc93e456757fa95497b2af9b045d4deChia-I Wu lib = open_library(driverPath); 1525541988578054345ca70b7ed7972710396e61b44Chia-I Wu 1536f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_WINDOWS) 1545541988578054345ca70b7ed7972710396e61b44Chia-I Wu /* XXX untested */ 1555541988578054345ca70b7ed7972710396e61b44Chia-I Wu if (lib) 1565541988578054345ca70b7ed7972710396e61b44Chia-I Wu mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain"); 1576f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#elif defined(_EGL_OS_UNIX) 1585541988578054345ca70b7ed7972710396e61b44Chia-I Wu if (lib) { 159496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu union { 160496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu _EGLMain_t func; 161496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu void *ptr; 162496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu } tmp = { NULL }; 163496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu /* direct cast gives a warning when compiled with -pedantic */ 164496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu tmp.ptr = dlsym(lib, "_eglMain"); 165496724b869d4258a64e8343d3ae66d08bfb19f7bChia-I Wu mainFunc = tmp.func; 1665541988578054345ca70b7ed7972710396e61b44Chia-I Wu if (!mainFunc) 1675541988578054345ca70b7ed7972710396e61b44Chia-I Wu error = dlerror(); 1685541988578054345ca70b7ed7972710396e61b44Chia-I Wu } 1695541988578054345ca70b7ed7972710396e61b44Chia-I Wu else { 1705541988578054345ca70b7ed7972710396e61b44Chia-I Wu error = dlerror(); 171ab0d13dd60c707f2c414fa9fe8e489a9e24a8aeeJonathan White } 172ab0d13dd60c707f2c414fa9fe8e489a9e24a8aeeJonathan White#endif 1735541988578054345ca70b7ed7972710396e61b44Chia-I Wu 174485528f2acb69940a7c757638127f716c0cb2654Jon Smirl if (!lib) { 1755541988578054345ca70b7ed7972710396e61b44Chia-I Wu _eglLog(_EGL_WARNING, "Could not open driver %s (%s)", 1765541988578054345ca70b7ed7972710396e61b44Chia-I Wu driverPath, error); 177485528f2acb69940a7c757638127f716c0cb2654Jon Smirl return NULL; 178485528f2acb69940a7c757638127f716c0cb2654Jon Smirl } 1796b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul 180485528f2acb69940a7c757638127f716c0cb2654Jon Smirl if (!mainFunc) { 1815541988578054345ca70b7ed7972710396e61b44Chia-I Wu _eglLog(_EGL_WARNING, "_eglMain not found in %s (%s)", 1825541988578054345ca70b7ed7972710396e61b44Chia-I Wu driverPath, error); 1830eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu if (lib) 1840eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu close_library(lib); 185485528f2acb69940a7c757638127f716c0cb2654Jon Smirl return NULL; 186adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul } 187485528f2acb69940a7c757638127f716c0cb2654Jon Smirl 1880eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu *handle = lib; 1890eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu return mainFunc; 1900eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 1910eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1920eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1930eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 194f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Load a module and create the driver object. 1950eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */ 196f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean 197f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglLoadModule(_EGLModule *mod) 1980eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{ 1990eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu _EGLMain_t mainFunc; 2000eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu lib_handle lib; 201f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDriver *drv; 2020eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 203c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod->Driver) 204c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu return EGL_TRUE; 205c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu 206c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod->BuiltIn) { 207c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu lib = (lib_handle) NULL; 208c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mainFunc = mod->BuiltIn; 209c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 210c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu else { 211c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mainFunc = _eglOpenLibrary(mod->Path, &lib); 212c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (!mainFunc) 213c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu return EGL_FALSE; 214c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 2150eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 216f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu drv = mainFunc(NULL); 217485528f2acb69940a7c757638127f716c0cb2654Jon Smirl if (!drv) { 2180eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu if (lib) 2190eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu close_library(lib); 220f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_FALSE; 221adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul } 2226b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul 2230eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu if (!drv->Name) { 224f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", mod->Path); 2250eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu drv->Name = "UNNAMED"; 2266b389b5c2facc431af0ffb21e3a9bcd532765367Brian Paul } 2270eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 228f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Handle = (void *) lib; 229f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver = drv; 230f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 231f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 232f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 233b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 2340eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 235f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 236f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload a module. 237f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 238f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 239f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadModule(_EGLModule *mod) 240f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 241d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#if defined(_EGL_OS_UNIX) 242f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* destroy the driver */ 243f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod->Driver && mod->Driver->Unload) 244f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver->Unload(mod->Driver); 245d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu 246d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu /* 247d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu * XXX At this point (atexit), the module might be the last reference to 248d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu * libEGL. Closing the module might unmap libEGL and give problems. 249d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu */ 250d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#if 0 251f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod->Handle) 252f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu close_library(mod->Handle); 253d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#endif 254d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#elif defined(_EGL_OS_WINDOWS) 255d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu /* XXX Windows unloads DLLs before atexit */ 256d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#endif 257f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 258f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver = NULL; 259f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Handle = NULL; 2600eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 2610eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 2620eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 2630eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 264f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add a module to the module array. 2650eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */ 266f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLModule * 267f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddModule(const char *path) 2680eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{ 269f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod; 270f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 2710eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 272f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) { 273f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglModules = _eglCreateArray("Module", 8); 274f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) 275f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return NULL; 276f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 277cf22fd5e5b13ccdb02ba0368ea722ede3bbc6de0Chia-I Wu 278f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* find duplicates */ 279f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu for (i = 0; i < _eglModules->Size; i++) { 280f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = _eglModules->Elements[i]; 281f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (strcmp(mod->Path, path) == 0) 282f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return mod; 283f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 284f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 285f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* allocate a new one */ 286f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = calloc(1, sizeof(*mod)); 287f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod) { 288f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Path = _eglstrdup(path); 289f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!mod->Path) { 290f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod); 291f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = NULL; 2920eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu } 2930eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu } 294f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod) { 295f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglAppendArray(_eglModules, (void *) mod); 296f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglLog(_EGL_DEBUG, "added %s to module array", mod->Path); 297f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 2980eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 299f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return mod; 300f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 301f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 302f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 303f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 304f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Free a module. 305f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 306f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 307f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglFreeModule(void *module) 308f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 309f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod = (_EGLModule *) module; 310f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 311f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglUnloadModule(mod); 312f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod->Path); 313f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod); 3140eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 3150eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 3160eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 3170eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 3180d089cbb48d099b833768556266114d537c91299Chia-I Wu * A loader function for use with _eglPreloadForEach. The loader data is the 3195d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * filename of the driver. This function stops on the first valid driver. 3205d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu */ 3215d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wustatic EGLBoolean 3220d089cbb48d099b833768556266114d537c91299Chia-I Wu_eglLoaderFile(const char *dir, size_t len, void *loader_data) 3235d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu{ 3245d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu char path[1024]; 3250d089cbb48d099b833768556266114d537c91299Chia-I Wu const char *filename = (const char *) loader_data; 3265d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu size_t flen = strlen(filename); 3275d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3285d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu /* make a full path */ 3295d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu if (len + flen + 2 > sizeof(path)) 3305d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return EGL_TRUE; 3315d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu if (len) { 3325d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu memcpy(path, dir, len); 3335d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu path[len++] = '/'; 3345d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 3355d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu memcpy(path + len, filename, flen); 3365d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu len += flen; 3375d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu path[len] = '\0'; 3385d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 339f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (library_suffix()) { 3405d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu const char *suffix = library_suffix(); 3415d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu size_t slen = strlen(suffix); 3425d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu const char *p; 3435d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu EGLBoolean need_suffix; 3445d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3455d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu p = filename + flen - slen; 3465d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu need_suffix = (p < filename || strcmp(p, suffix) != 0); 347f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (need_suffix) { 348f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* overflow */ 349f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (len + slen + 1 > sizeof(path)) 350f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 3515d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu strcpy(path + len, suffix); 3525d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 3535d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 354f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 355f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu#if defined(_EGL_OS_UNIX) 356f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* check if the file exists */ 357f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (access(path, F_OK)) 3585d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return EGL_TRUE; 359f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu#endif 360f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 361f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglAddModule(path); 362f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 363f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 364f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 365f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 3665d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 367f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 368f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Run the callback function on each driver directory. 3695d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * 3705d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * The process may end prematurely if the callback function returns false. 3715d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu */ 372f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 3735d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu_eglPreloadForEach(const char *search_path, 3740d089cbb48d099b833768556266114d537c91299Chia-I Wu EGLBoolean (*loader)(const char *, size_t, void *), 3750d089cbb48d099b833768556266114d537c91299Chia-I Wu void *loader_data) 3765d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu{ 3775d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu const char *cur, *next; 3785d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu size_t len; 3795d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3805d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu cur = search_path; 3815d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu while (cur) { 3825d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu next = strchr(cur, ':'); 3835d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu len = (next) ? next - cur : strlen(cur); 3845d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 38588af76ce94834d795c11445b1c82b7aa874b87d5Igor Oliveira if (!loader(cur, len, loader_data)) 3865d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu break; 3875d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3885d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu cur = (next) ? next + 1 : NULL; 3895d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 3905d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu} 3915d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3925d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 3935d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu/** 3945d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu * Return a list of colon-separated driver directories. 3955d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu */ 3965d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wustatic const char * 3975d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu_eglGetSearchPath(void) 3985d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu{ 399ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu static char search_path[1024]; 4005d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 4016f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) 402ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (search_path[0] == '\0') { 403ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu char *buf = search_path; 404ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu size_t len = sizeof(search_path); 405ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu EGLBoolean use_env; 406ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu char dir_sep; 4075d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu int ret; 4085d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 4096f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX) 410ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu use_env = (geteuid() == getuid() && getegid() == getgid()); 411ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu dir_sep = '/'; 412ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu#else 413ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu use_env = EGL_TRUE; 414ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu dir_sep = '\\'; 415ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu#endif 416ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 417ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (use_env) { 418ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu char *p; 419ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 420ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu /* extract the dirname from EGL_DRIVER */ 421ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu p = getenv("EGL_DRIVER"); 422ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (p && strchr(p, dir_sep)) { 423ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu ret = _eglsnprintf(buf, len, "%s", p); 424ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (ret > 0 && ret < len) { 425ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu p = strrchr(buf, dir_sep); 426ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu *p++ = ':'; 427ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 428ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu len -= p - buf; 429ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu buf = p; 430ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 431ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 432ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 433ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu /* append EGL_DRIVERS_PATH */ 434ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu p = getenv("EGL_DRIVERS_PATH"); 435ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (p) { 436ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu ret = _eglsnprintf(buf, len, "%s:", p); 437ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (ret > 0 && ret < len) { 438ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu buf += ret; 439ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu len -= ret; 440ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 441ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 442ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu } 443ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu else { 4446fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu _eglLog(_EGL_DEBUG, 4456fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu "ignore EGL_DRIVERS_PATH for setuid/setgid binaries"); 4466fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu } 4476fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu 448ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu ret = _eglsnprintf(buf, len, "%s", _EGL_DRIVER_SEARCH_DIR); 449ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu if (ret < 0 || ret >= len) 450ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu search_path[0] = '\0'; 451ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu 452ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu _eglLog(_EGL_DEBUG, "EGL search path is %s", search_path); 4535d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu } 454ad00a92ee720c275d3852faea4e442a8da876ca2Chia-I Wu#endif /* defined(_EGL_OS_UNIX) || defined(_EGL_OS_WINDOWS) */ 4555d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 4565d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu return search_path; 4575d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu} 4585d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 4595d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu 4605d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu/** 461f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add the user driver to the module array. 462b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu * 463f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * The user driver is specified by EGL_DRIVER. 464b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */ 4651e4f412242391000eea3fd28452865c3d27f987dChia-I Wustatic EGLBoolean 466f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddUserDriver(void) 467b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 4685d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu const char *search_path = _eglGetSearchPath(); 46921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu char *env; 470f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu size_t name_len = 0; 471b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 472b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu env = getenv("EGL_DRIVER"); 4736f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#if defined(_EGL_OS_UNIX) 4746fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu if (env && strchr(env, '/')) { 4755d8646c41ff3022692fa9d7f5f1644a2a60641e4Chia-I Wu search_path = ""; 4766fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu if ((geteuid() != getuid() || getegid() != getgid())) { 4776fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu _eglLog(_EGL_DEBUG, 4786fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu "ignore EGL_DRIVER for setuid/setgid binaries"); 4796fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu env = NULL; 4806fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu } 4816fd8b6a9e22f474117281b00d15c548c29b8197fChia-I Wu } 482f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu else if (env) { 483f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu char *suffix = strchr(env, '.'); 484f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu name_len = (suffix) ? suffix - env : strlen(env); 485f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu } 486f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu#else 487f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu if (env) 488f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu name_len = strlen(env); 4896f690caddcd9afbea6ed3e743b0c95c02c85e5efChia-I Wu#endif /* _EGL_OS_UNIX */ 490f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 491f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu /* 492f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu * Try built-in drivers first if we know the driver name. This makes sure 493f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu * we do not load the outdated external driver that is still on the 494f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu * filesystem. 495f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu */ 496f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu if (name_len) { 497c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLModule *mod; 498c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu EGLint i; 499c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu 500c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu for (i = 0; _eglBuiltInDrivers[i].name; i++) { 501f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu if (strlen(_eglBuiltInDrivers[i].name) == name_len && 502f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu !strncmp(_eglBuiltInDrivers[i].name, env, name_len)) { 503c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod = _eglAddModule(env); 504c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod) 505c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod->BuiltIn = _eglBuiltInDrivers[i].main; 506f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 507f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu return EGL_TRUE; 508c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 509c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 510f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu } 511f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 512f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu /* otherwise, treat env as a path */ 513f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu if (env) { 514f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu _eglPreloadForEach(search_path, _eglLoaderFile, (void *) env); 5151e4f412242391000eea3fd28452865c3d27f987dChia-I Wu 5161e4f412242391000eea3fd28452865c3d27f987dChia-I Wu return EGL_TRUE; 517c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 5181e4f412242391000eea3fd28452865c3d27f987dChia-I Wu 5191e4f412242391000eea3fd28452865c3d27f987dChia-I Wu return EGL_FALSE; 520f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 521b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 522f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 523f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 52449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu * Add egl_gallium to the module array. 52549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu */ 52649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wustatic void 52749ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu_eglAddGalliumDriver(void) 52849ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu{ 52949ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu#ifndef _EGL_BUILT_IN_DRIVER_GALLIUM 53049ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu void *external = (void *) "egl_gallium"; 53149ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu _eglPreloadForEach(_eglGetSearchPath(), _eglLoaderFile, external); 53249ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu#endif 53349ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu} 53449ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu 53549ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu 53649ed5bb28d501cd6751bd59dc25a60a4293bcd75Chia-I Wu/** 537c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu * Add built-in drivers to the module array. 538f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 539f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 540c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu_eglAddBuiltInDrivers(void) 541f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 542c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLModule *mod; 543f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 544f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 545c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu for (i = 0; _eglBuiltInDrivers[i].name; i++) { 546c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod = _eglAddModule(_eglBuiltInDrivers[i].name); 547c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod) 548c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod->BuiltIn = _eglBuiltInDrivers[i].main; 54921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu } 550f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 551b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 552f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 553f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 554f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add drivers to the module array. Drivers will be loaded as they are matched 555f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * to displays. 556f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 557f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean 558f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddDrivers(void) 559f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 560f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (_eglModules) 561f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 562f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 5631e4f412242391000eea3fd28452865c3d27f987dChia-I Wu if (!_eglAddUserDriver()) { 5641e4f412242391000eea3fd28452865c3d27f987dChia-I Wu /* 5651e4f412242391000eea3fd28452865c3d27f987dChia-I Wu * Add other drivers only when EGL_DRIVER is not set. The order here 5661e4f412242391000eea3fd28452865c3d27f987dChia-I Wu * decides the priorities. 5671e4f412242391000eea3fd28452865c3d27f987dChia-I Wu */ 5681e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglAddGalliumDriver(); 5691e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglAddBuiltInDrivers(); 5701e4f412242391000eea3fd28452865c3d27f987dChia-I Wu } 571f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 572f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return (_eglModules != NULL); 573b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu} 574b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 575b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 576b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu/** 577655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * A helper function for _eglMatchDriver. It finds the first driver that can 578655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * initialize the display and return. 579b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */ 580655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wustatic _EGLDriver * 581655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchAndInitialize(_EGLDisplay *dpy) 582b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 583655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLDriver *drv = NULL; 584655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu EGLint i = 0; 5854afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 586f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglAddDrivers()) { 5871e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglLog(_EGL_WARNING, "failed to find any driver"); 588655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return NULL; 5894afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu } 590b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 591655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (dpy->Driver) { 592655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = dpy->Driver; 593655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* no re-matching? */ 594655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!drv->API.Initialize(drv, dpy)) 595655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = NULL; 596655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return drv; 597655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu } 598b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 599655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu while (i < _eglModules->Size) { 600655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; 601655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 602655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!_eglLoadModule(mod)) { 603655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* remove invalid modules */ 604655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglEraseArray(_eglModules, i, _eglFreeModule); 605655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu continue; 606655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu } 607655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 608655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (mod->Driver->API.Initialize(mod->Driver, dpy)) { 609655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = mod->Driver; 610655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu break; 611f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 612f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu else { 613655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu i++; 614f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 615f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 6164afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 617655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return drv; 618655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu} 619b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 6204afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 621655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu/** 622655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * Match a display to a driver. The display is initialized unless test_only is 623655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * true. The matching is done by finding the first driver that can initialize 624655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * the display. 625655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu */ 626655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_EGLDriver * 627655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only) 628655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu{ 629655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLDriver *best_drv; 630f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 631655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu assert(!dpy->Initialized); 632f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 633655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglLockMutex(&_eglModuleMutex); 634655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 635655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* set options */ 636655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu dpy->Options.TestOnly = test_only; 637a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu dpy->Options.UseFallback = EGL_FALSE; 638655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 639655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu best_drv = _eglMatchAndInitialize(dpy); 640a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu if (!best_drv) { 641a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu dpy->Options.UseFallback = EGL_TRUE; 642a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu best_drv = _eglMatchAndInitialize(dpy); 643a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu } 6440eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 645f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglUnlockMutex(&_eglModuleMutex); 646f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 647f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (best_drv) { 648655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglLog(_EGL_DEBUG, "the best driver is %s%s", 649655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu best_drv->Name, (test_only) ? " (test only) " : ""); 650655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!test_only) { 651f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu dpy->Driver = best_drv; 652f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu dpy->Initialized = EGL_TRUE; 653f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 654f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 655f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 656f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return best_drv; 657e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul} 658e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul 659f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 660f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu__eglMustCastToProperFunctionPointerType 661f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglGetDriverProc(const char *procname) 662681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg{ 663f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 664f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLProc proc = NULL; 665f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 666f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) { 667f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* load the driver for the default display */ 668f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 669f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDisplay *dpy = _eglLookupDisplay(egldpy); 670f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE)) 671f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return NULL; 672f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 673681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 674f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu for (i = 0; i < _eglModules->Size; i++) { 675f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; 676681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 677f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!mod->Driver) 678f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu break; 679f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu proc = mod->Driver->API.GetProcAddress(mod->Driver, procname); 680f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (proc) 681afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu break; 682afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu } 683681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 684f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return proc; 685f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 686f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 687681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 688f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 689f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload all drivers. 690f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 691f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wuvoid 692f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadDrivers(void) 693f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 694f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* this is called at atexit time */ 695f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (_eglModules) { 696f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglDestroyArray(_eglModules, _eglFreeModule); 697f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglModules = NULL; 698f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 699681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg} 700681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 701e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul 702e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul/** 703e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * Invoke a callback function on each EGL search path. 704e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * 705e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * The first argument of the callback function is the name of the search path. 706e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu * The second argument is the length of the name. 707e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu */ 708e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wuvoid 709e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu_eglSearchPathForEach(EGLBoolean (*callback)(const char *, size_t, void *), 710e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu void *callback_data) 711e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu{ 712e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu const char *search_path = _eglGetSearchPath(); 713e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu _eglPreloadForEach(search_path, callback, callback_data); 714e8ba2812e6995d1ec95c972a1b48ac29a99531ddChia-I Wu} 715