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
;