1 /************************************************************************** 2 * 3 * Copyright 2008 VMware, Inc. 4 * Copyright 2009-2010 Chia-I Wu <olvaffe (at) gmail.com> 5 * Copyright 2010-2011 LunarG, Inc. 6 * All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the 10 * "Software"), to deal in the Software without restriction, including 11 * without limitation the rights to use, copy, modify, merge, publish, 12 * distribute, sub license, and/or sell copies of the Software, and to 13 * permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the 17 * next paragraph) shall be included in all copies or substantial portions 18 * of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 * 28 **************************************************************************/ 29 30 31 /** 32 * Functions for choosing and opening/loading device drivers. 33 */ 34 35 36 #include <assert.h> 37 #include <string.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include "c11/threads.h" 41 42 #include "egldefines.h" 43 #include "egldisplay.h" 44 #include "egldriver.h" 45 #include "egllog.h" 46 47 #include "util/debug.h" 48 49 static mtx_t _eglModuleMutex = _MTX_INITIALIZER_NP; 50 static _EGLDriver *_eglDriver; 51 52 static _EGLDriver * 53 _eglGetDriver(void) 54 { 55 mtx_lock(&_eglModuleMutex); 56 57 if (!_eglDriver) 58 _eglDriver = _eglBuiltInDriver(); 59 60 mtx_unlock(&_eglModuleMutex); 61 62 return _eglDriver; 63 } 64 65 static _EGLDriver * 66 _eglMatchAndInitialize(_EGLDisplay *dpy) 67 { 68 if (_eglGetDriver()) 69 if (_eglDriver->API.Initialize(_eglDriver, dpy)) 70 return _eglDriver; 71 72 return NULL; 73 } 74 75 /** 76 * Match a display to a driver. The matching is done by finding the first 77 * driver that can initialize the display. 78 */ 79 _EGLDriver * 80 _eglMatchDriver(_EGLDisplay *dpy) 81 { 82 _EGLDriver *best_drv; 83 84 assert(!dpy->Initialized); 85 86 /* set options */ 87 dpy->Options.ForceSoftware = 88 env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false); 89 90 best_drv = _eglMatchAndInitialize(dpy); 91 if (!best_drv && !dpy->Options.ForceSoftware) { 92 dpy->Options.ForceSoftware = EGL_TRUE; 93 best_drv = _eglMatchAndInitialize(dpy); 94 } 95 96 if (best_drv) { 97 _eglLog(_EGL_DEBUG, "the best driver is %s", 98 best_drv->Name); 99 dpy->Driver = best_drv; 100 dpy->Initialized = EGL_TRUE; 101 } 102 103 return best_drv; 104 } 105 106 __eglMustCastToProperFunctionPointerType 107 _eglGetDriverProc(const char *procname) 108 { 109 if (_eglGetDriver()) 110 return _eglDriver->API.GetProcAddress(_eglDriver, procname); 111 112 return NULL; 113 } 114 115 /** 116 * Unload all drivers. 117 */ 118 void 119 _eglUnloadDrivers(void) 120 { 121 /* this is called at atexit time */ 122 free(_eglDriver); 123 _eglDriver = NULL; 124 } 125