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"
42 struct egl_g3d_loader egl_g3d_loader
;
44 static struct st_module
{
47 struct util_dl_library
*lib
;
49 } st_modules
[ST_API_COUNT
];
51 static struct pipe_module
{
54 struct util_dl_library
*lib
;
55 const struct drm_driver_descriptor
*drmdd
;
56 struct pipe_screen
*(*swrast_create_screen
)(struct sw_winsys
*);
60 loader_strdup(const char *s
)
62 size_t len
= (s
) ? strlen(s
) : 0;
63 char *t
= MALLOC(len
+ 1);
72 dlopen_st_module_cb(const char *dir
, size_t len
, void *callback_data
)
74 struct st_module
*stmod
=
75 (struct st_module
*) callback_data
;
80 ret
= util_snprintf(path
, sizeof(path
),
81 "%.*s/" ST_PREFIX
"%s" UTIL_DL_EXT
, len
, dir
, stmod
->name
);
84 ret
= util_snprintf(path
, sizeof(path
),
85 ST_PREFIX
"%s" UTIL_DL_EXT
, stmod
->name
);
88 if (ret
> 0 && ret
< sizeof(path
)) {
89 stmod
->lib
= util_dl_open(path
);
91 _eglLog(_EGL_DEBUG
, "loaded %s", path
);
98 load_st_module(struct st_module
*stmod
,
99 const char *name
, const char *procname
)
101 struct st_api
*(*create_api
)(void);
103 _eglLog(_EGL_DEBUG
, "searching for st module %s", name
);
105 stmod
->name
= loader_strdup(name
);
107 _eglSearchPathForEach(dlopen_st_module_cb
, (void *) stmod
);
109 stmod
->lib
= util_dl_open(NULL
);
112 create_api
= (struct st_api
*(*)(void))
113 util_dl_get_proc_address(stmod
->lib
, procname
);
115 stmod
->stapi
= create_api();
118 util_dl_close(stmod
->lib
);
128 return (stmod
->stapi
!= NULL
);
132 dlopen_pipe_module_cb(const char *dir
, size_t len
, void *callback_data
)
134 struct pipe_module
*pmod
= (struct pipe_module
*) callback_data
;
139 ret
= util_snprintf(path
, sizeof(path
),
140 "%.*s/" PIPE_PREFIX
"%s" UTIL_DL_EXT
, len
, dir
, pmod
->name
);
143 ret
= util_snprintf(path
, sizeof(path
),
144 PIPE_PREFIX
"%s" UTIL_DL_EXT
, pmod
->name
);
146 if (ret
> 0 && ret
< sizeof(path
)) {
147 pmod
->lib
= util_dl_open(path
);
149 _eglLog(_EGL_DEBUG
, "loaded %s", path
);
156 load_pipe_module(struct pipe_module
*pmod
, const char *name
)
158 pmod
->name
= loader_strdup(name
);
162 _eglLog(_EGL_DEBUG
, "searching for pipe module %s", pmod
->name
);
163 _eglSearchPathForEach(dlopen_pipe_module_cb
, (void *) pmod
);
165 pmod
->drmdd
= (const struct drm_driver_descriptor
*)
166 util_dl_get_proc_address(pmod
->lib
, "driver_descriptor");
168 /* sanity check on the name */
169 if (pmod
->drmdd
&& strcmp(pmod
->drmdd
->name
, pmod
->name
) != 0)
173 if (pmod
->drmdd
&& !pmod
->drmdd
->driver_name
) {
174 pmod
->swrast_create_screen
=
175 (struct pipe_screen
*(*)(struct sw_winsys
*))
176 util_dl_get_proc_address(pmod
->lib
, "swrast_create_screen");
177 if (!pmod
->swrast_create_screen
)
182 util_dl_close(pmod
->lib
);
187 return (pmod
->drmdd
!= NULL
);
190 static struct st_api
*
191 get_st_api_full(enum st_api_type api
, enum st_profile_type profile
)
193 struct st_module
*stmod
= &st_modules
[api
];
194 const char *names
[8], *symbol
;
197 if (stmod
->initialized
)
202 symbol
= ST_CREATE_OPENGL_SYMBOL
;
204 case ST_PROFILE_OPENGL_ES1
:
205 names
[count
++] = "GLESv1_CM";
206 names
[count
++] = "GL";
208 case ST_PROFILE_OPENGL_ES2
:
209 names
[count
++] = "GLESv2";
210 names
[count
++] = "GL";
213 names
[count
++] = "GL";
218 symbol
= ST_CREATE_OPENVG_SYMBOL
;
219 names
[count
++] = "OpenVG";
223 assert(!"Unknown API Type\n");
227 /* NULL means the process itself */
228 names
[count
++] = NULL
;
230 for (i
= 0; i
< count
; i
++) {
231 if (load_st_module(stmod
, names
[i
], symbol
))
236 EGLint level
= (egl_g3d_loader
.profile_masks
[api
]) ?
237 _EGL_WARNING
: _EGL_DEBUG
;
238 _eglLog(level
, "unable to load " ST_PREFIX
"%s" UTIL_DL_EXT
, names
[0]);
241 stmod
->initialized
= TRUE
;
246 static struct st_api
*
247 get_st_api(enum st_api_type api
)
249 enum st_profile_type profile
= ST_PROFILE_DEFAULT
;
251 /* determine the profile from the linked libraries */
252 if (api
== ST_API_OPENGL
) {
253 struct util_dl_library
*self
;
255 self
= util_dl_open(NULL
);
257 if (util_dl_get_proc_address(self
, "glColor4x"))
258 profile
= ST_PROFILE_OPENGL_ES1
;
259 else if (util_dl_get_proc_address(self
, "glShaderBinary"))
260 profile
= ST_PROFILE_OPENGL_ES2
;
265 return get_st_api_full(api
, profile
);
268 static struct st_api
*
269 guess_gl_api(enum st_profile_type profile
)
271 return get_st_api_full(ST_API_OPENGL
, profile
);
274 static struct pipe_module
*
275 get_pipe_module(const char *name
)
277 struct pipe_module
*pmod
= NULL
;
283 for (i
= 0; i
< Elements(pipe_modules
); i
++) {
284 if (!pipe_modules
[i
].initialized
||
285 strcmp(pipe_modules
[i
].name
, name
) == 0) {
286 pmod
= &pipe_modules
[i
];
293 if (!pmod
->initialized
) {
294 load_pipe_module(pmod
, name
);
295 pmod
->initialized
= TRUE
;
301 static struct pipe_screen
*
302 create_drm_screen(const char *name
, int fd
)
304 struct pipe_module
*pmod
= get_pipe_module(name
);
305 return (pmod
&& pmod
->drmdd
&& pmod
->drmdd
->create_screen
) ?
306 pmod
->drmdd
->create_screen(fd
) : NULL
;
309 static struct pipe_screen
*
310 create_sw_screen(struct sw_winsys
*ws
)
312 struct pipe_module
*pmod
= get_pipe_module("swrast");
313 return (pmod
&& pmod
->swrast_create_screen
) ?
314 pmod
->swrast_create_screen(ws
) : NULL
;
317 static const struct egl_g3d_loader
*
320 /* TODO detect at runtime? */
322 egl_g3d_loader
.profile_masks
[ST_API_OPENGL
] |= ST_PROFILE_DEFAULT_MASK
;
325 egl_g3d_loader
.profile_masks
[ST_API_OPENGL
] |= ST_PROFILE_OPENGL_ES1_MASK
;
328 egl_g3d_loader
.profile_masks
[ST_API_OPENGL
] |= ST_PROFILE_OPENGL_ES2_MASK
;
331 egl_g3d_loader
.profile_masks
[ST_API_OPENVG
] |= ST_PROFILE_DEFAULT_MASK
;
334 egl_g3d_loader
.get_st_api
= get_st_api
;
335 egl_g3d_loader
.guess_gl_api
= guess_gl_api
;
336 egl_g3d_loader
.create_drm_screen
= create_drm_screen
;
337 egl_g3d_loader
.create_sw_screen
= create_sw_screen
;
339 return &egl_g3d_loader
;
347 for (i
= 0; i
< ST_API_COUNT
; i
++) {
348 struct st_module
*stmod
= &st_modules
[i
];
351 stmod
->stapi
->destroy(stmod
->stapi
);
355 util_dl_close(stmod
->lib
);
362 stmod
->initialized
= FALSE
;
364 for (i
= 0; i
< Elements(pipe_modules
); i
++) {
365 struct pipe_module
*pmod
= &pipe_modules
[i
];
367 if (!pmod
->initialized
)
371 pmod
->swrast_create_screen
= NULL
;
373 util_dl_close(pmod
->lib
);
380 pmod
->initialized
= FALSE
;
385 egl_g3d_unload(_EGLDriver
*drv
)
387 egl_g3d_destroy_driver(drv
);
392 _eglMain(const char *args
)
394 const struct egl_g3d_loader
*loader
;
397 loader
= loader_init();
398 drv
= egl_g3d_create_driver(loader
);
404 drv
->Name
= "Gallium";
405 drv
->Unload
= egl_g3d_unload
;