egldriver.c revision b8e80941
1/************************************************************************** 2 * 3 * Copyright 2008 VMware, Inc. 4 * Copyright 2009-2010 Chia-I Wu <olvaffe@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 49static mtx_t _eglModuleMutex = _MTX_INITIALIZER_NP; 50static _EGLDriver *_eglDriver; 51 52static _EGLDriver * 53_eglGetDriver(void) 54{ 55 mtx_lock(&_eglModuleMutex); 56 57 if (!_eglDriver) { 58 _eglDriver = calloc(1, sizeof(*_eglDriver)); 59 if (!_eglDriver) { 60 mtx_unlock(&_eglModuleMutex); 61 return NULL; 62 } 63 _eglInitDriverFallbacks(_eglDriver); 64 _eglInitDriver(_eglDriver); 65 } 66 67 mtx_unlock(&_eglModuleMutex); 68 69 return _eglDriver; 70} 71 72static _EGLDriver * 73_eglMatchAndInitialize(_EGLDisplay *disp) 74{ 75 if (_eglGetDriver()) 76 if (_eglDriver->API.Initialize(_eglDriver, disp)) 77 return _eglDriver; 78 79 return NULL; 80} 81 82/** 83 * Match a display to a driver. The matching is done by finding the first 84 * driver that can initialize the display. 85 */ 86_EGLDriver * 87_eglMatchDriver(_EGLDisplay *disp) 88{ 89 _EGLDriver *best_drv; 90 91 assert(!disp->Initialized); 92 93 /* set options */ 94 disp->Options.ForceSoftware = 95 env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false); 96 97 best_drv = _eglMatchAndInitialize(disp); 98 if (!best_drv && !disp->Options.ForceSoftware) { 99 disp->Options.ForceSoftware = EGL_TRUE; 100 best_drv = _eglMatchAndInitialize(disp); 101 } 102 103 if (best_drv) { 104 disp->Driver = best_drv; 105 disp->Initialized = EGL_TRUE; 106 } 107 108 return best_drv; 109} 110 111__eglMustCastToProperFunctionPointerType 112_eglGetDriverProc(const char *procname) 113{ 114 if (_eglGetDriver()) 115 return _eglDriver->API.GetProcAddress(_eglDriver, procname); 116 117 return NULL; 118} 119 120/** 121 * Unload all drivers. 122 */ 123void 124_eglUnloadDrivers(void) 125{ 126 /* this is called at atexit time */ 127 free(_eglDriver); 128 _eglDriver = NULL; 129} 130