egldriver.c revision 3593f37fd7b599e217bd1f894ac671a14a058b8d
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{ 99d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#if defined(_EGL_OS_UNIX) 100f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* destroy the driver */ 101f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod->Driver && mod->Driver->Unload) 102f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver->Unload(mod->Driver); 103d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu 104d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#elif defined(_EGL_OS_WINDOWS) 105d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu /* XXX Windows unloads DLLs before atexit */ 106d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#endif 107f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 108f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod->Driver = NULL; 1090eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 1100eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1110eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1120eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 113f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add a module to the module array. 1140eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */ 115f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLModule * 116209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov_eglAddModule(const char *name) 1170eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{ 118f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod; 119f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 1200eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 121f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) { 122f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglModules = _eglCreateArray("Module", 8); 123f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) 124f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return NULL; 125f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 126cf22fd5e5b13ccdb02ba0368ea722ede3bbc6de0Chia-I Wu 127f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* find duplicates */ 128f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu for (i = 0; i < _eglModules->Size; i++) { 129f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = _eglModules->Elements[i]; 130209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (strcmp(mod->Name, name) == 0) 131f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return mod; 132f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 133f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 134f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* allocate a new one */ 135f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = calloc(1, sizeof(*mod)); 136f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod) { 1373593f37fd7b599e217bd1f894ac671a14a058b8dEmil Velikov mod->Name = strdup(name); 138209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (!mod->Name) { 139f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod); 140f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu mod = NULL; 1410eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu } 1420eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu } 143f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (mod) { 144f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglAppendArray(_eglModules, (void *) mod); 145209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov _eglLog(_EGL_DEBUG, "added %s to module array", mod->Name); 146f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 1470eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 148f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return mod; 149f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 150f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 151f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 152f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 153f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Free a module. 154f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 155f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 156f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglFreeModule(void *module) 157f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 158f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod = (_EGLModule *) module; 159f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 160f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglUnloadModule(mod); 161209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov free(mod->Name); 162f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu free(mod); 1630eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu} 1640eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1650eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 1660eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/** 167f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add the user driver to the module array. 168b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu * 169f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * The user driver is specified by EGL_DRIVER. 170b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */ 1711e4f412242391000eea3fd28452865c3d27f987dChia-I Wustatic EGLBoolean 172f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddUserDriver(void) 173b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 17421b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu char *env; 175b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 176b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu env = getenv("EGL_DRIVER"); 177209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (env) { 178c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu EGLint i; 179c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu 180c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu for (i = 0; _eglBuiltInDrivers[i].name; i++) { 181209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov if (!strcmp(_eglBuiltInDrivers[i].name, env)) { 182209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov _EGLModule *mod = _eglAddModule(env); 183c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod) 184c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod->BuiltIn = _eglBuiltInDrivers[i].main; 185f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 186f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu return EGL_TRUE; 187c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 188c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu } 189f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu } 190f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu 1911e4f412242391000eea3fd28452865c3d27f987dChia-I Wu return EGL_FALSE; 192f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 193b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 194f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 195f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 196c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu * Add built-in drivers to the module array. 197f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 198f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void 199c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu_eglAddBuiltInDrivers(void) 200f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 201c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu _EGLModule *mod; 202f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 203f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 204c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu for (i = 0; _eglBuiltInDrivers[i].name; i++) { 205c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod = _eglAddModule(_eglBuiltInDrivers[i].name); 206c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu if (mod) 207c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu mod->BuiltIn = _eglBuiltInDrivers[i].main; 20821b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu } 209f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 210b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 211f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 212f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 213f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add drivers to the module array. Drivers will be loaded as they are matched 214f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * to displays. 215f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 216f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean 217f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddDrivers(void) 218f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 219f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (_eglModules) 220f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return EGL_TRUE; 221f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 2221e4f412242391000eea3fd28452865c3d27f987dChia-I Wu if (!_eglAddUserDriver()) { 2231e4f412242391000eea3fd28452865c3d27f987dChia-I Wu /* 2241e4f412242391000eea3fd28452865c3d27f987dChia-I Wu * Add other drivers only when EGL_DRIVER is not set. The order here 2251e4f412242391000eea3fd28452865c3d27f987dChia-I Wu * decides the priorities. 2261e4f412242391000eea3fd28452865c3d27f987dChia-I Wu */ 2271e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglAddBuiltInDrivers(); 2281e4f412242391000eea3fd28452865c3d27f987dChia-I Wu } 229f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 230f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return (_eglModules != NULL); 231b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu} 232b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 233b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 234b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu/** 235655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * A helper function for _eglMatchDriver. It finds the first driver that can 236655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * initialize the display and return. 237b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */ 238655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wustatic _EGLDriver * 239655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchAndInitialize(_EGLDisplay *dpy) 240b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{ 241655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLDriver *drv = NULL; 242655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu EGLint i = 0; 2434afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 244f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglAddDrivers()) { 2451e4f412242391000eea3fd28452865c3d27f987dChia-I Wu _eglLog(_EGL_WARNING, "failed to find any driver"); 246655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return NULL; 2474afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu } 248b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 249655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (dpy->Driver) { 250655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = dpy->Driver; 251655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* no re-matching? */ 252655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!drv->API.Initialize(drv, dpy)) 253655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = NULL; 254655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return drv; 255655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu } 256b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 257655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu while (i < _eglModules->Size) { 258655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; 259655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 260655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!_eglLoadModule(mod)) { 261655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* remove invalid modules */ 262655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglEraseArray(_eglModules, i, _eglFreeModule); 263655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu continue; 264655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu } 265655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 266655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (mod->Driver->API.Initialize(mod->Driver, dpy)) { 267655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu drv = mod->Driver; 268655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu break; 269f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 270f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu else { 271655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu i++; 272f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 273f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 2744afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 275655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu return drv; 276655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu} 277b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu 2784afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu 279655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu/** 280655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * Match a display to a driver. The display is initialized unless test_only is 281655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * true. The matching is done by finding the first driver that can initialize 282655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * the display. 283655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu */ 284655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_EGLDriver * 285655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only) 286655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu{ 287655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _EGLDriver *best_drv; 288f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 289655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu assert(!dpy->Initialized); 290f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 291efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikov mtx_lock(&_eglModuleMutex); 292655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 293655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu /* set options */ 294655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu dpy->Options.TestOnly = test_only; 295a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu dpy->Options.UseFallback = EGL_FALSE; 296655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu 297655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu best_drv = _eglMatchAndInitialize(dpy); 298a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu if (!best_drv) { 299a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu dpy->Options.UseFallback = EGL_TRUE; 300a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu best_drv = _eglMatchAndInitialize(dpy); 301a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu } 3020eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu 303efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikov mtx_unlock(&_eglModuleMutex); 304f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 305f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (best_drv) { 306655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu _eglLog(_EGL_DEBUG, "the best driver is %s%s", 307655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu best_drv->Name, (test_only) ? " (test only) " : ""); 308655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu if (!test_only) { 309f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu dpy->Driver = best_drv; 310f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu dpy->Initialized = EGL_TRUE; 311f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 312f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 313f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 314f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return best_drv; 315e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul} 316e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul 317f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 318f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu__eglMustCastToProperFunctionPointerType 319f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglGetDriverProc(const char *procname) 320681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg{ 321f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLint i; 322f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLProc proc = NULL; 323f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 324f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!_eglModules) { 325f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* load the driver for the default display */ 326f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 327f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLDisplay *dpy = _eglLookupDisplay(egldpy); 328f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE)) 329f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return NULL; 330f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 331681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 332f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu for (i = 0; i < _eglModules->Size; i++) { 333f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i]; 334681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 335f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (!mod->Driver) 336f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu break; 337f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu proc = mod->Driver->API.GetProcAddress(mod->Driver, procname); 338f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (proc) 339afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu break; 340afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu } 341681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 342f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu return proc; 343f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} 344f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu 345681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg 346f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/** 347f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload all drivers. 348f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */ 349f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wuvoid 350f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadDrivers(void) 351f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{ 352f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu /* this is called at atexit time */ 353f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu if (_eglModules) { 354f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglDestroyArray(_eglModules, _eglFreeModule); 355f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu _eglModules = NULL; 356f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu } 357681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg} 358