Home | History | Annotate | Download | only in main
      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