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