1f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu/************************************************************************** 2f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * 3877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2008 VMware, Inc. 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> 40efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikov#include "c11/threads.h" 411e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu 42e084fe54f93c9d51df99812b76d3299b0cff57a3Brian Paul#include "egldefines.h" 43adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldisplay.h" 44adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldriver.h" 45b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul#include "egllog.h" 46adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul 47f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wutypedef struct _egl_module { 48209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov char *Name; 49c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLMain_t BuiltIn; 50f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDriver *Driver; 51f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} _EGLModule; 52f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 53efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikovstatic mtx_t _eglModuleMutex = _MTX_INITIALIZER_NP; 54f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLArray *_eglModules; 55f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 56c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wuconst struct { 57c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu const char *name; 58c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLMain_t main; 59c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu} _eglBuiltInDrivers[] = { 60c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_DRI2 61c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu { "egl_dri2", _eglBuiltInDriverDRI2 }, 62c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#endif 63400b833592d9aad7b2c4627a897380642d52189fAlexander von Gluck IV#ifdef _EGL_BUILT_IN_DRIVER_HAIKU 64400b833592d9aad7b2c4627a897380642d52189fAlexander von Gluck IV { "egl_haiku", _eglBuiltInDriverHaiku }, 65400b833592d9aad7b2c4627a897380642d52189fAlexander von Gluck IV#endif 66c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu { NULL, NULL } 67c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu}; 68f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 69a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul/** 70f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Load a module and create the driver object. 710eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */ 72f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean 73f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglLoadModule(_EGLModule *mod) 740eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{ 75f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDriver *drv; 760eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 77c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod->Driver) 78c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu return EGL_TRUE; 79c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu 80209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (!mod->BuiltIn) 81c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu return EGL_FALSE; 820eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 83209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov drv = mod->BuiltIn(NULL); 84209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (!drv || !drv->Name) 85f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_FALSE; 860eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 87f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver = drv; 88f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 89f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 90f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 91b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 920eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 93f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 94f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload a module. 95f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 96f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 97f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadModule(_EGLModule *mod) 98f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 99f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* destroy the driver */ 100f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod->Driver && mod->Driver->Unload) 101f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver->Unload(mod->Driver); 102d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu 103f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver = NULL; 1040eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 1050eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1060eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1070eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 108f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add a module to the module array. 1090eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */ 110f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLModule * 111209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov_eglAddModule(const char *name) 1120eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{ 113f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod; 114f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 1150eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 116f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) { 117f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglModules = _eglCreateArray("Module", 8); 118f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) 119f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return NULL; 120f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 121cf22fd5e5b13ccdb02ba0368ea722ede3bbc6de0Chia-I Wu 122f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* find duplicates */ 123f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu for (i = 0; i < _eglModules->Size; i++) { 124f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = _eglModules->Elements[i]; 125209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (strcmp(mod->Name, name) == 0) 126f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return mod; 127f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 128f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 129f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* allocate a new one */ 130f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = calloc(1, sizeof(*mod)); 131f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod) { 1323593f37fd7b599e217bd1f894ac671a14a058b8dEmil Velikov mod->Name = strdup(name); 133209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (!mod->Name) { 134f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod); 135f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = NULL; 1360eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu } 1370eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu } 138f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod) { 139f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglAppendArray(_eglModules, (void *) mod); 140209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov _eglLog(_EGL_DEBUG, "added %s to module array", mod->Name); 141f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 1420eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 143f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return mod; 144f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 145f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 146f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 147f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 148f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Free a module. 149f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 150f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 151f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglFreeModule(void *module) 152f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 153f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod = (_EGLModule *) module; 154f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 155f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglUnloadModule(mod); 156209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov free(mod->Name); 157f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod); 1580eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 1590eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1600eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1610eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 162f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add the user driver to the module array. 163b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu * 164f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * The user driver is specified by EGL_DRIVER. 165b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */ 1661e4f412242391000eea3fd28452865c3d27f987dChia-I Wustatic EGLBoolean 167f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddUserDriver(void) 168b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 16921b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu char *env; 170b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 171b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu env = getenv("EGL_DRIVER"); 172209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (env) { 173c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu EGLint i; 174c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu 175c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu for (i = 0; _eglBuiltInDrivers[i].name; i++) { 176209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (!strcmp(_eglBuiltInDrivers[i].name, env)) { 177209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov _EGLModule *mod = _eglAddModule(env); 178c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod) 179c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod->BuiltIn = _eglBuiltInDrivers[i].main; 180f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 181f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu return EGL_TRUE; 182c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 183c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 184f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu } 185f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 1861e4f412242391000eea3fd28452865c3d27f987dChia-I Wu return EGL_FALSE; 187f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 188b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 189f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 190f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 191c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu * Add built-in drivers to the module array. 192f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 193f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 194c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu_eglAddBuiltInDrivers(void) 195f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 196c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLModule *mod; 197f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 198f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 199c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu for (i = 0; _eglBuiltInDrivers[i].name; i++) { 200c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod = _eglAddModule(_eglBuiltInDrivers[i].name); 201c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod) 202c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod->BuiltIn = _eglBuiltInDrivers[i].main; 20321b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu } 204f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 205b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 206f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 207f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 208f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add drivers to the module array. Drivers will be loaded as they are matched 209f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * to displays. 210f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 211f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean 212f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddDrivers(void) 213f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 214f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (_eglModules) 215f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 216f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 2171e4f412242391000eea3fd28452865c3d27f987dChia-I Wu if (!_eglAddUserDriver()) { 2181e4f412242391000eea3fd28452865c3d27f987dChia-I Wu /* 2191e4f412242391000eea3fd28452865c3d27f987dChia-I Wu * Add other drivers only when EGL_DRIVER is not set. The order here 2201e4f412242391000eea3fd28452865c3d27f987dChia-I Wu * decides the priorities. 2211e4f412242391000eea3fd28452865c3d27f987dChia-I Wu */ 2221e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglAddBuiltInDrivers(); 2231e4f412242391000eea3fd28452865c3d27f987dChia-I Wu } 224f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 225f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return (_eglModules != NULL); 226b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu} 227b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 228b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 229b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu/** 230655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * A helper function for _eglMatchDriver. It finds the first driver that can 231655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * initialize the display and return. 232b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */ 233655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wustatic _EGLDriver * 234655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchAndInitialize(_EGLDisplay *dpy) 235b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 236655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLDriver *drv = NULL; 237655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu EGLint i = 0; 2384afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 239f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglAddDrivers()) { 2401e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglLog(_EGL_WARNING, "failed to find any driver"); 241655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return NULL; 2424afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu } 243b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 244655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (dpy->Driver) { 245655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = dpy->Driver; 246655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* no re-matching? */ 247655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!drv->API.Initialize(drv, dpy)) 248655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = NULL; 249655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return drv; 250655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu } 251b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 252655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu while (i < _eglModules->Size) { 253655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; 254655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 255655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!_eglLoadModule(mod)) { 256655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* remove invalid modules */ 257655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglEraseArray(_eglModules, i, _eglFreeModule); 258655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu continue; 259655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu } 260655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 261655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (mod->Driver->API.Initialize(mod->Driver, dpy)) { 262655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = mod->Driver; 263655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu break; 264f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 265f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu else { 266655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu i++; 267f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 268f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 2694afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 270655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return drv; 271655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu} 272b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 2734afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 274655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu/** 275655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * Match a display to a driver. The display is initialized unless test_only is 276655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * true. The matching is done by finding the first driver that can initialize 277655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * the display. 278655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu */ 279655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_EGLDriver * 280655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only) 281655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu{ 282655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLDriver *best_drv; 283f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 284655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu assert(!dpy->Initialized); 285f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 286efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikov mtx_lock(&_eglModuleMutex); 287655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 288655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* set options */ 289655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu dpy->Options.TestOnly = test_only; 290a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu dpy->Options.UseFallback = EGL_FALSE; 291655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 292655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu best_drv = _eglMatchAndInitialize(dpy); 293a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu if (!best_drv) { 294a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu dpy->Options.UseFallback = EGL_TRUE; 295a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu best_drv = _eglMatchAndInitialize(dpy); 296a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu } 2970eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 298efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikov mtx_unlock(&_eglModuleMutex); 299f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 300f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (best_drv) { 301655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglLog(_EGL_DEBUG, "the best driver is %s%s", 302655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu best_drv->Name, (test_only) ? " (test only) " : ""); 303655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!test_only) { 304f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu dpy->Driver = best_drv; 305f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu dpy->Initialized = EGL_TRUE; 306f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 307f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 308f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 309f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return best_drv; 310e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul} 311e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul 312f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 313f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu__eglMustCastToProperFunctionPointerType 314f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglGetDriverProc(const char *procname) 315681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg{ 316f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 317f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLProc proc = NULL; 318f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 319f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) { 320f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* load the driver for the default display */ 321f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 322f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDisplay *dpy = _eglLookupDisplay(egldpy); 323f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE)) 324f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return NULL; 325f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 326681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 327f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu for (i = 0; i < _eglModules->Size; i++) { 328f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; 329681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 330f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!mod->Driver) 331f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu break; 332f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu proc = mod->Driver->API.GetProcAddress(mod->Driver, procname); 333f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (proc) 334afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu break; 335afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu } 336681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 337f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return proc; 338f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 339f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 340681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 341f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 342f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload all drivers. 343f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 344f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wuvoid 345f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadDrivers(void) 346f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 347f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* this is called at atexit time */ 348f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (_eglModules) { 349f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglDestroyArray(_eglModules, _eglFreeModule); 350f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglModules = NULL; 351f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 352681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg} 353