egldriver.c revision 3593f37fd7b599e217bd1f894ac671a14a058b8d
1f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu/**************************************************************************
2f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
3877128505431adaf817dc8069172ebe4a1cdf5d8José Fonseca * Copyright 2008 VMware, Inc.
4f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
5f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Copyright 2010-2011 LunarG, Inc.
6f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * All Rights Reserved.
7f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
8f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a
9f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * copy of this software and associated documentation files (the
10f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * "Software"), to deal in the Software without restriction, including
11f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * without limitation the rights to use, copy, modify, merge, publish,
12f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * distribute, sub license, and/or sell copies of the Software, and to
13f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * permit persons to whom the Software is furnished to do so, subject to
14f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * the following conditions:
15f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
16f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * The above copyright notice and this permission notice (including the
17f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * next paragraph) shall be included in all copies or substantial portions
18f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * of the Software.
19f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
20f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
23f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu * DEALINGS IN THE SOFTWARE.
27f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu *
28f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu **************************************************************************/
29f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu
30f2001df508fda599a18b3586d2775e970a3db13aChia-I Wu
316052af172f0241e6678cd16efac0a0f14f40146cBrian Paul/**
326052af172f0241e6678cd16efac0a0f14f40146cBrian Paul * Functions for choosing and opening/loading device drivers.
336052af172f0241e6678cd16efac0a0f14f40146cBrian Paul */
346052af172f0241e6678cd16efac0a0f14f40146cBrian Paul
356052af172f0241e6678cd16efac0a0f14f40146cBrian Paul
36adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <assert.h>
3711a261ef4f1d4100c46f73ad51e7e4ed57cc1b5eBrian Paul#include <string.h>
38adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include <stdio.h>
390c8908c411c434eda318b41b4f2a370a1e794831Brian Paul#include <stdlib.h>
40efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikov#include "c11/threads.h"
411e6c10f4be9e36cc052a6b47fb2cb1eae60caa00Chia-I Wu
42e084fe54f93c9d51df99812b76d3299b0cff57a3Brian Paul#include "egldefines.h"
43adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldisplay.h"
44adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul#include "egldriver.h"
45b711eb793b68bb0c4561e5e345b76453dfac286bBrian Paul#include "egllog.h"
46adbff7e977c7c768e752a24fb643d68bdf961bfeBrian Paul
47f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wutypedef struct _egl_module {
48209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov   char *Name;
49c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   _EGLMain_t BuiltIn;
50f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLDriver *Driver;
51f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu} _EGLModule;
52f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
53efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikovstatic mtx_t _eglModuleMutex = _MTX_INITIALIZER_NP;
54f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLArray *_eglModules;
55f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
56c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wuconst struct {
57c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   const char *name;
58c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   _EGLMain_t main;
59c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu} _eglBuiltInDrivers[] = {
60c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#ifdef _EGL_BUILT_IN_DRIVER_DRI2
61c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   { "egl_dri2", _eglBuiltInDriverDRI2 },
62c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu#endif
63400b833592d9aad7b2c4627a897380642d52189fAlexander von Gluck IV#ifdef _EGL_BUILT_IN_DRIVER_HAIKU
64400b833592d9aad7b2c4627a897380642d52189fAlexander von Gluck IV   { "egl_haiku", _eglBuiltInDriverHaiku },
65400b833592d9aad7b2c4627a897380642d52189fAlexander von Gluck IV#endif
66c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   { NULL, NULL }
67c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu};
68f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
69a8533d54930f8fa989036c197ad20b0778ec0cacBrian Paul/**
70f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Load a module and create the driver object.
710eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */
72f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean
73f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglLoadModule(_EGLModule *mod)
740eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{
75f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLDriver *drv;
760eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
77c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   if (mod->Driver)
78c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      return EGL_TRUE;
79c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu
80209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov   if (!mod->BuiltIn)
81c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu         return EGL_FALSE;
820eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
83209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov   drv = mod->BuiltIn(NULL);
84209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov   if (!drv || !drv->Name)
85f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      return EGL_FALSE;
860eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
87f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   mod->Driver = drv;
88f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
89f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return EGL_TRUE;
90f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
91b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
920eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
93f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
94f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload a module.
95f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
96f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void
97f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadModule(_EGLModule *mod)
98f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
99d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#if defined(_EGL_OS_UNIX)
100f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   /* destroy the driver */
101f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (mod->Driver && mod->Driver->Unload)
102f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      mod->Driver->Unload(mod->Driver);
103d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu
104d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#elif defined(_EGL_OS_WINDOWS)
105d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu   /* XXX Windows unloads DLLs before atexit */
106d6b1478ff0499059661df145efe469e7b28ff7bfChia-I Wu#endif
107f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
108f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   mod->Driver = NULL;
1090eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu}
1100eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
1110eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
1120eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/**
113f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add a module to the module array.
1140eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu */
115f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic _EGLModule *
116209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov_eglAddModule(const char *name)
1170eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu{
118f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLModule *mod;
119f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   EGLint i;
1200eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
121f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (!_eglModules) {
122f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglModules = _eglCreateArray("Module", 8);
123f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (!_eglModules)
124f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         return NULL;
125f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
126cf22fd5e5b13ccdb02ba0368ea722ede3bbc6de0Chia-I Wu
127f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   /* find duplicates */
128f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   for (i = 0; i < _eglModules->Size; i++) {
129f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      mod = _eglModules->Elements[i];
130209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov      if (strcmp(mod->Name, name) == 0)
131f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         return mod;
132f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
133f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
134f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   /* allocate a new one */
135f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   mod = calloc(1, sizeof(*mod));
136f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (mod) {
1373593f37fd7b599e217bd1f894ac671a14a058b8dEmil Velikov      mod->Name = strdup(name);
138209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov      if (!mod->Name) {
139f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         free(mod);
140f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         mod = NULL;
1410eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu      }
1420eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu   }
143f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (mod) {
144f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglAppendArray(_eglModules, (void *) mod);
145209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov      _eglLog(_EGL_DEBUG, "added %s to module array", mod->Name);
146f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
1470eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
148f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return mod;
149f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
150f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
151f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
152f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
153f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Free a module.
154f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
155f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void
156f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglFreeModule(void *module)
157f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
158f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLModule *mod = (_EGLModule *) module;
159f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
160f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _eglUnloadModule(mod);
161209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov   free(mod->Name);
162f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   free(mod);
1630eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu}
1640eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
1650eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
1660eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu/**
167f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add the user driver to the module array.
168b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu *
169f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * The user driver is specified by EGL_DRIVER.
170b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */
1711e4f412242391000eea3fd28452865c3d27f987dChia-I Wustatic EGLBoolean
172f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddUserDriver(void)
173b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{
17421b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu   char *env;
175b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
176b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu   env = getenv("EGL_DRIVER");
177209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov   if (env) {
178c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      EGLint i;
179c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu
180c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      for (i = 0; _eglBuiltInDrivers[i].name; i++) {
181209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov         if (!strcmp(_eglBuiltInDrivers[i].name, env)) {
182209360bbb91bb10346ebc509db3d8173ea32f6b1Emil Velikov            _EGLModule *mod = _eglAddModule(env);
183c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu            if (mod)
184c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu               mod->BuiltIn = _eglBuiltInDrivers[i].main;
185f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu
186f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu            return EGL_TRUE;
187c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu         }
188c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      }
189f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu   }
190f36cba6cf3d51a3937d3bb429609d258399751a0Chia-I Wu
1911e4f412242391000eea3fd28452865c3d27f987dChia-I Wu   return EGL_FALSE;
192f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
193b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
194f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
195f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
196c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu * Add built-in drivers to the module array.
197f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
198f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic void
199c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu_eglAddBuiltInDrivers(void)
200f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
201c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   _EGLModule *mod;
202f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   EGLint i;
203f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
204c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu   for (i = 0; _eglBuiltInDrivers[i].name; i++) {
205c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      mod = _eglAddModule(_eglBuiltInDrivers[i].name);
206c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu      if (mod)
207c98ea26e16b6458b4385d6558936696e4d099455Chia-I Wu         mod->BuiltIn = _eglBuiltInDrivers[i].main;
20821b2c0a6e5ecb6d542bd7d3750c5a0b745104eddChia-I Wu   }
209f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
210b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
211f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
212f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
213f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Add drivers to the module array.  Drivers will be loaded as they are matched
214f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * to displays.
215f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
216f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wustatic EGLBoolean
217f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglAddDrivers(void)
218f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
219f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (_eglModules)
220f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      return EGL_TRUE;
221f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
2221e4f412242391000eea3fd28452865c3d27f987dChia-I Wu   if (!_eglAddUserDriver()) {
2231e4f412242391000eea3fd28452865c3d27f987dChia-I Wu      /*
2241e4f412242391000eea3fd28452865c3d27f987dChia-I Wu       * Add other drivers only when EGL_DRIVER is not set.  The order here
2251e4f412242391000eea3fd28452865c3d27f987dChia-I Wu       * decides the priorities.
2261e4f412242391000eea3fd28452865c3d27f987dChia-I Wu       */
2271e4f412242391000eea3fd28452865c3d27f987dChia-I Wu      _eglAddBuiltInDrivers();
2281e4f412242391000eea3fd28452865c3d27f987dChia-I Wu   }
229f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
230f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return (_eglModules != NULL);
231b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu}
232b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
233b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
234b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu/**
235655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * A helper function for _eglMatchDriver.  It finds the first driver that can
236655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * initialize the display and return.
237b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu */
238655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wustatic _EGLDriver *
239655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchAndInitialize(_EGLDisplay *dpy)
240b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu{
241655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   _EGLDriver *drv = NULL;
242655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   EGLint i = 0;
2434afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu
244f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (!_eglAddDrivers()) {
2451e4f412242391000eea3fd28452865c3d27f987dChia-I Wu      _eglLog(_EGL_WARNING, "failed to find any driver");
246655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      return NULL;
2474afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu   }
248b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
249655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   if (dpy->Driver) {
250655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      drv = dpy->Driver;
251655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      /* no re-matching? */
252655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      if (!drv->API.Initialize(drv, dpy))
253655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         drv = NULL;
254655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      return drv;
255655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   }
256b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
257655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   while (i < _eglModules->Size) {
258655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
259655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu
260655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      if (!_eglLoadModule(mod)) {
261655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         /* remove invalid modules */
262655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         _eglEraseArray(_eglModules, i, _eglFreeModule);
263655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         continue;
264655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      }
265655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu
266655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      if (mod->Driver->API.Initialize(mod->Driver, dpy)) {
267655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         drv = mod->Driver;
268655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         break;
269f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      }
270f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      else {
271655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu         i++;
272f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      }
273f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
2744afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu
275655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   return drv;
276655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu}
277b3bcd33f7a8b32ce4ea6e979e9cc764d0f903ae9Chia-I Wu
2784afe24808ee253c44c65b855f65bd0749c1e1524Chia-I Wu
279655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu/**
280655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * Match a display to a driver.  The display is initialized unless test_only is
281655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * true.  The matching is done by finding the first driver that can initialize
282655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu * the display.
283655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu */
284655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_EGLDriver *
285655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu_eglMatchDriver(_EGLDisplay *dpy, EGLBoolean test_only)
286655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu{
287655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   _EGLDriver *best_drv;
288f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
289655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   assert(!dpy->Initialized);
290f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
291efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikov   mtx_lock(&_eglModuleMutex);
292655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu
293655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   /* set options */
294655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   dpy->Options.TestOnly = test_only;
295a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu   dpy->Options.UseFallback = EGL_FALSE;
296655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu
297655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu   best_drv = _eglMatchAndInitialize(dpy);
298a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu   if (!best_drv) {
299a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu      dpy->Options.UseFallback = EGL_TRUE;
300a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu      best_drv = _eglMatchAndInitialize(dpy);
301a22a332fc7cc54d4d0973dcd21a90159cc51de1aChia-I Wu   }
3020eaa02c836821556c1e8d0141f49f57e23f2548dChia-I Wu
303efe87f1a801c61d087cd2b29a2c150453241c3d4Emil Velikov   mtx_unlock(&_eglModuleMutex);
304f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
305f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (best_drv) {
306655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      _eglLog(_EGL_DEBUG, "the best driver is %s%s",
307655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu            best_drv->Name, (test_only) ? " (test only) " : "");
308655e4598927728a663f4cfcd6babdf7e5ad83f77Chia-I Wu      if (!test_only) {
309f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         dpy->Driver = best_drv;
310f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         dpy->Initialized = EGL_TRUE;
311f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      }
312f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
313f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
314f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return best_drv;
315e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul}
316e3805cad0d15ed25ce8f6c5a1f1ea913e5d0986aBrian Paul
317f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
318f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu__eglMustCastToProperFunctionPointerType
319f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglGetDriverProc(const char *procname)
320681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg{
321f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   EGLint i;
322f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   _EGLProc proc = NULL;
323f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
324f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (!_eglModules) {
325f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      /* load the driver for the default display */
326f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      EGLDisplay egldpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
327f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _EGLDisplay *dpy = _eglLookupDisplay(egldpy);
328f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (!dpy || !_eglMatchDriver(dpy, EGL_TRUE))
329f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         return NULL;
330f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
331681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg
332f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   for (i = 0; i < _eglModules->Size; i++) {
333f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _EGLModule *mod = (_EGLModule *) _eglModules->Elements[i];
334681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg
335f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (!mod->Driver)
336f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu         break;
337f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      proc = mod->Driver->API.GetProcAddress(mod->Driver, procname);
338f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      if (proc)
339afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu         break;
340afcea9b115cdfa0a6c948784f753d38b43240d25Chia-I Wu   }
341681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg
342f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   return proc;
343f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu}
344f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu
345681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg
346f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu/**
347f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu * Unload all drivers.
348f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu */
349f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wuvoid
350f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu_eglUnloadDrivers(void)
351f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu{
352f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   /* this is called at atexit time */
353f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   if (_eglModules) {
354f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglDestroyArray(_eglModules, _eglFreeModule);
355f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu      _eglModules = NULL;
356f2aa361f3b58a91780c9358b3f8716f6434074c7Chia-I Wu   }
357681fd73f1e95d43425b946a250b241bfdb0ce1c8Kristian Høgsberg}
358