egldriver.c revision b8e80941
1848b8605Smrg/************************************************************************** 2848b8605Smrg * 3848b8605Smrg * Copyright 2008 VMware, Inc. 4848b8605Smrg * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com> 5848b8605Smrg * Copyright 2010-2011 LunarG, Inc. 6848b8605Smrg * All Rights Reserved. 7848b8605Smrg * 8848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 9848b8605Smrg * copy of this software and associated documentation files (the 10848b8605Smrg * "Software"), to deal in the Software without restriction, including 11848b8605Smrg * without limitation the rights to use, copy, modify, merge, publish, 12848b8605Smrg * distribute, sub license, and/or sell copies of the Software, and to 13848b8605Smrg * permit persons to whom the Software is furnished to do so, subject to 14848b8605Smrg * the following conditions: 15848b8605Smrg * 16848b8605Smrg * The above copyright notice and this permission notice (including the 17848b8605Smrg * next paragraph) shall be included in all copies or substantial portions 18848b8605Smrg * of the Software. 19848b8605Smrg * 20848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26848b8605Smrg * DEALINGS IN THE SOFTWARE. 27848b8605Smrg * 28848b8605Smrg **************************************************************************/ 29848b8605Smrg 30848b8605Smrg 31848b8605Smrg/** 32848b8605Smrg * Functions for choosing and opening/loading device drivers. 33848b8605Smrg */ 34848b8605Smrg 35848b8605Smrg 36848b8605Smrg#include <assert.h> 37848b8605Smrg#include <string.h> 38848b8605Smrg#include <stdio.h> 39848b8605Smrg#include <stdlib.h> 40b8e80941Smrg#include "c11/threads.h" 41848b8605Smrg 42848b8605Smrg#include "egldefines.h" 43848b8605Smrg#include "egldisplay.h" 44848b8605Smrg#include "egldriver.h" 45848b8605Smrg#include "egllog.h" 46848b8605Smrg 47b8e80941Smrg#include "util/debug.h" 48848b8605Smrg 49b8e80941Smrgstatic mtx_t _eglModuleMutex = _MTX_INITIALIZER_NP; 50b8e80941Smrgstatic _EGLDriver *_eglDriver; 51848b8605Smrg 52b8e80941Smrgstatic _EGLDriver * 53b8e80941Smrg_eglGetDriver(void) 54848b8605Smrg{ 55b8e80941Smrg mtx_lock(&_eglModuleMutex); 56848b8605Smrg 57b8e80941Smrg if (!_eglDriver) { 58b8e80941Smrg _eglDriver = calloc(1, sizeof(*_eglDriver)); 59b8e80941Smrg if (!_eglDriver) { 60b8e80941Smrg mtx_unlock(&_eglModuleMutex); 61848b8605Smrg return NULL; 62848b8605Smrg } 63b8e80941Smrg _eglInitDriverFallbacks(_eglDriver); 64b8e80941Smrg _eglInitDriver(_eglDriver); 65848b8605Smrg } 66848b8605Smrg 67b8e80941Smrg mtx_unlock(&_eglModuleMutex); 68848b8605Smrg 69b8e80941Smrg return _eglDriver; 70848b8605Smrg} 71848b8605Smrg 72848b8605Smrgstatic _EGLDriver * 73b8e80941Smrg_eglMatchAndInitialize(_EGLDisplay *disp) 74848b8605Smrg{ 75b8e80941Smrg if (_eglGetDriver()) 76b8e80941Smrg if (_eglDriver->API.Initialize(_eglDriver, disp)) 77b8e80941Smrg return _eglDriver; 78848b8605Smrg 79b8e80941Smrg return NULL; 80848b8605Smrg} 81848b8605Smrg 82848b8605Smrg/** 83b8e80941Smrg * Match a display to a driver. The matching is done by finding the first 84b8e80941Smrg * driver that can initialize the display. 85848b8605Smrg */ 86848b8605Smrg_EGLDriver * 87b8e80941Smrg_eglMatchDriver(_EGLDisplay *disp) 88848b8605Smrg{ 89848b8605Smrg _EGLDriver *best_drv; 90848b8605Smrg 91b8e80941Smrg assert(!disp->Initialized); 92848b8605Smrg 93848b8605Smrg /* set options */ 94b8e80941Smrg disp->Options.ForceSoftware = 95b8e80941Smrg env_var_as_boolean("LIBGL_ALWAYS_SOFTWARE", false); 96848b8605Smrg 97b8e80941Smrg best_drv = _eglMatchAndInitialize(disp); 98b8e80941Smrg if (!best_drv && !disp->Options.ForceSoftware) { 99b8e80941Smrg disp->Options.ForceSoftware = EGL_TRUE; 100b8e80941Smrg best_drv = _eglMatchAndInitialize(disp); 101848b8605Smrg } 102848b8605Smrg 103848b8605Smrg if (best_drv) { 104b8e80941Smrg disp->Driver = best_drv; 105b8e80941Smrg disp->Initialized = EGL_TRUE; 106848b8605Smrg } 107848b8605Smrg 108848b8605Smrg return best_drv; 109848b8605Smrg} 110848b8605Smrg 111848b8605Smrg__eglMustCastToProperFunctionPointerType 112848b8605Smrg_eglGetDriverProc(const char *procname) 113848b8605Smrg{ 114b8e80941Smrg if (_eglGetDriver()) 115b8e80941Smrg return _eglDriver->API.GetProcAddress(_eglDriver, procname); 116848b8605Smrg 117b8e80941Smrg return NULL; 118848b8605Smrg} 119848b8605Smrg 120848b8605Smrg/** 121848b8605Smrg * Unload all drivers. 122848b8605Smrg */ 123848b8605Smrgvoid 124848b8605Smrg_eglUnloadDrivers(void) 125848b8605Smrg{ 126848b8605Smrg /* this is called at atexit time */ 127b8e80941Smrg free(_eglDriver); 128b8e80941Smrg _eglDriver = NULL; 129848b8605Smrg} 130