2
* Mesa 3-D graphics library
5
* Copyright (C) 2010 LunarG Inc.
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
* copy of this software and associated documentation files (the "Software"),
9
* to deal in the Software without restriction, including without limitation
10
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
* and/or sell copies of the Software, and to permit persons to whom the
12
* Software is furnished to do so, subject to the following conditions:
14
* The above copyright notice and this permission notice shall be included
15
* in all copies or substantial portions of the Software.
17
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
* DEALINGS IN THE SOFTWARE.
26
* Chia-I Wu <olv@lunarg.com>
29
#include "util/u_debug.h"
30
#include "util/u_string.h"
31
#include "util/u_memory.h"
32
#include "util/u_dl.h"
33
#include "egldriver.h"
36
#include "state_tracker/st_api.h"
37
#include "state_tracker/drm_driver.h"
38
#include "common/egl_g3d_loader.h"
40
struct egl_g3d_loader egl_g3d_loader;
42
static struct st_module {
45
struct util_dl_library *lib;
47
} st_modules[ST_API_COUNT];
49
static struct pipe_module {
52
struct util_dl_library *lib;
53
const struct drm_driver_descriptor *drmdd;
54
struct pipe_screen *(*swrast_create_screen)(struct sw_winsys *);
58
loader_strdup(const char *s)
60
size_t len = (s) ? strlen(s) : 0;
61
char *t = MALLOC(len + 1);
70
dlopen_st_module_cb(const char *dir, size_t len, void *callback_data)
72
struct st_module *stmod =
73
(struct st_module *) callback_data;
78
ret = util_snprintf(path, sizeof(path),
79
"%.*s/" ST_PREFIX "%s" UTIL_DL_EXT, len, dir, stmod->name);
82
ret = util_snprintf(path, sizeof(path),
83
ST_PREFIX "%s" UTIL_DL_EXT, stmod->name);
86
if (ret > 0 && ret < sizeof(path)) {
87
stmod->lib = util_dl_open(path);
89
_eglLog(_EGL_DEBUG, "loaded %s", path);
96
load_st_module(struct st_module *stmod,
97
const char *name, const char *procname)
99
struct st_api *(*create_api)(void);
101
stmod->name = loader_strdup(name);
103
_eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod);
105
stmod->lib = util_dl_open(NULL);
108
create_api = (struct st_api *(*)(void))
109
util_dl_get_proc_address(stmod->lib, procname);
111
stmod->stapi = create_api();
114
util_dl_close(stmod->lib);
124
return (stmod->stapi != NULL);
128
dlopen_pipe_module_cb(const char *dir, size_t len, void *callback_data)
130
struct pipe_module *pmod = (struct pipe_module *) callback_data;
135
ret = util_snprintf(path, sizeof(path),
136
"%.*s/" PIPE_PREFIX "%s" UTIL_DL_EXT, len, dir, pmod->name);
139
ret = util_snprintf(path, sizeof(path),
140
PIPE_PREFIX "%s" UTIL_DL_EXT, pmod->name);
142
if (ret > 0 && ret < sizeof(path)) {
143
pmod->lib = util_dl_open(path);
145
_eglLog(_EGL_DEBUG, "loaded %s", path);
152
load_pipe_module(struct pipe_module *pmod, const char *name)
154
pmod->name = loader_strdup(name);
158
_eglLog(_EGL_DEBUG, "searching for pipe module %s", pmod->name);
159
_eglSearchPathForEach(dlopen_pipe_module_cb, (void *) pmod);
161
pmod->drmdd = (const struct drm_driver_descriptor *)
162
util_dl_get_proc_address(pmod->lib, "driver_descriptor");
164
/* sanity check on the name */
165
if (pmod->drmdd && strcmp(pmod->drmdd->name, pmod->name) != 0)
169
if (pmod->drmdd && !pmod->drmdd->driver_name) {
170
pmod->swrast_create_screen =
171
(struct pipe_screen *(*)(struct sw_winsys *))
172
util_dl_get_proc_address(pmod->lib, "swrast_create_screen");
173
if (!pmod->swrast_create_screen)
178
util_dl_close(pmod->lib);
186
return (pmod->drmdd != NULL);
189
static struct st_api *
190
get_st_api(enum st_api_type api)
192
struct st_module *stmod = &st_modules[api];
193
const char *names[8], *symbol;
196
if (stmod->initialized)
201
symbol = ST_CREATE_OPENGL_SYMBOL;
202
names[count++] = "GL";
204
case ST_API_OPENGL_ES1:
205
symbol = ST_CREATE_OPENGL_ES1_SYMBOL;
206
names[count++] = "GLESv1_CM";
207
names[count++] = "GL";
209
case ST_API_OPENGL_ES2:
210
symbol = ST_CREATE_OPENGL_ES2_SYMBOL;
211
names[count++] = "GLESv2";
212
names[count++] = "GL";
215
symbol = ST_CREATE_OPENVG_SYMBOL;
216
names[count++] = "OpenVG";
220
assert(!"Unknown API Type\n");
224
/* NULL means the process itself */
225
names[count++] = NULL;
227
for (i = 0; i < count; i++) {
228
if (load_st_module(stmod, names[i], symbol))
233
EGLint level = (egl_g3d_loader.api_mask & (1 << api)) ?
234
_EGL_WARNING : _EGL_DEBUG;
235
_eglLog(level, "unable to load " ST_PREFIX "%s" UTIL_DL_EXT, names[0]);
238
stmod->initialized = TRUE;
243
static struct st_api *
246
struct st_api *stapi;
255
/* determine the api from the loaded libraries */
256
for (i = 0; gl_apis[i] != -1; i++) {
257
if (st_modules[gl_apis[i]].stapi) {
262
/* determine the api from the linked libraries */
264
struct util_dl_library *self = util_dl_open(NULL);
267
if (util_dl_get_proc_address(self, "glColor4d"))
269
else if (util_dl_get_proc_address(self, "glColor4x"))
270
api = ST_API_OPENGL_ES1;
271
else if (util_dl_get_proc_address(self, "glShaderBinary"))
272
api = ST_API_OPENGL_ES2;
277
stapi = (api != -1) ? get_st_api(api) : NULL;
279
for (i = 0; gl_apis[i] != -1; i++) {
281
stapi = get_st_api(api);
290
static struct pipe_module *
291
get_pipe_module(const char *name)
293
struct pipe_module *pmod = NULL;
299
for (i = 0; i < Elements(pipe_modules); i++) {
300
if (!pipe_modules[i].initialized ||
301
strcmp(pipe_modules[i].name, name) == 0) {
302
pmod = &pipe_modules[i];
309
if (!pmod->initialized) {
310
load_pipe_module(pmod, name);
311
pmod->initialized = TRUE;
317
static struct pipe_screen *
318
create_drm_screen(const char *name, int fd)
320
struct pipe_module *pmod = get_pipe_module(name);
321
return (pmod && pmod->drmdd->create_screen) ?
322
pmod->drmdd->create_screen(fd) : NULL;
325
static struct pipe_screen *
326
create_sw_screen(struct sw_winsys *ws)
328
struct pipe_module *pmod = get_pipe_module("swrast");
329
return (pmod && pmod->swrast_create_screen) ?
330
pmod->swrast_create_screen(ws) : NULL;
333
static const struct egl_g3d_loader *
338
/* TODO detect at runtime? */
340
api_mask |= 1 << ST_API_OPENGL;
343
api_mask |= 1 << ST_API_OPENGL_ES1;
346
api_mask |= 1 << ST_API_OPENGL_ES2;
349
api_mask |= 1 << ST_API_OPENVG;
352
egl_g3d_loader.api_mask = api_mask;
353
egl_g3d_loader.get_st_api = get_st_api;
354
egl_g3d_loader.guess_gl_api = guess_gl_api;
355
egl_g3d_loader.create_drm_screen = create_drm_screen;
356
egl_g3d_loader.create_sw_screen = create_sw_screen;
358
return &egl_g3d_loader;
366
for (i = 0; i < ST_API_COUNT; i++) {
367
struct st_module *stmod = &st_modules[i];
370
stmod->stapi->destroy(stmod->stapi);
374
util_dl_close(stmod->lib);
381
stmod->initialized = FALSE;
383
for (i = 0; i < Elements(pipe_modules); i++) {
384
struct pipe_module *pmod = &pipe_modules[i];
386
if (!pmod->initialized)
390
pmod->swrast_create_screen = NULL;
392
util_dl_close(pmod->lib);
399
pmod->initialized = FALSE;
404
egl_g3d_unload(_EGLDriver *drv)
406
egl_g3d_destroy_driver(drv);
411
_eglMain(const char *args)
413
const struct egl_g3d_loader *loader;
416
loader = loader_init();
417
drv = egl_g3d_create_driver(loader);
423
drv->Name = "Gallium";
424
drv->Unload = egl_g3d_unload;