2 * Functions for choosing and opening/loading device drivers.
10 #include "eglconfig.h"
11 #include "eglcontext.h"
12 #include "egldefines.h"
13 #include "egldisplay.h"
14 #include "egldriver.h"
15 #include "eglglobals.h"
19 #include "eglscreen.h"
20 #include "eglstring.h"
21 #include "eglsurface.h"
23 #if defined(_EGL_PLATFORM_X)
25 #include <sys/types.h>
31 * Wrappers for dlopen/dlclose()
33 #if defined(_EGL_PLATFORM_WINDOWS)
36 /* XXX Need to decide how to do dynamic name lookup on Windows */
37 static const char DefaultDriverName
[] = "TBD";
39 typedef HMODULE lib_handle
;
42 open_library(const char *filename
)
44 return LoadLibrary(filename
);
48 close_library(HMODULE lib
)
61 #elif defined(_EGL_PLATFORM_X)
64 static const char DefaultDriverName
[] = "egl_softpipe";
66 typedef void * lib_handle
;
69 open_library(const char *filename
)
71 return dlopen(filename
, RTLD_LAZY
);
75 close_library(void *lib
)
88 #else /* _EGL_PLATFORM_NO_OS */
90 static const char DefaultDriverName
[] = "builtin";
92 typedef void *lib_handle
;
95 open_library(const char *filename
)
97 return (void *) filename
;
101 close_library(void *lib
)
117 * Choose a driver for a given display.
118 * The caller may free() the returned strings.
121 _eglChooseDriver(_EGLDisplay
*dpy
, char **argsRet
)
124 const char *args
= NULL
;
125 const char *suffix
= NULL
;
128 path
= getenv("EGL_DRIVER");
130 path
= _eglstrdup(path
);
132 #if defined(_EGL_PLATFORM_X)
133 if (!path
&& dpy
&& dpy
->NativeDisplay
) {
134 /* assume (wrongly!) that the native display is a display string */
135 path
= _eglSplitDisplayString((const char *) dpy
->NativeDisplay
, &args
);
138 #elif defined(_EGL_PLATFORM_WINDOWS)
140 #else /* _EGL_PLATFORM_NO_OS */
142 /* force the use of the default driver */
143 _eglLog(_EGL_DEBUG
, "ignore EGL_DRIVER");
151 path
= _eglstrdup(DefaultDriverName
);
153 /* append suffix if there isn't */
154 p
= strrchr(path
, '.');
156 size_t len
= strlen(path
);
157 char *tmp
= malloc(len
+ strlen(suffix
) + 2);
159 memcpy(tmp
, path
, len
);
162 strcat(tmp
+ len
, suffix
);
170 *argsRet
= (args
) ? _eglstrdup(args
) : NULL
;
177 * Open the named driver and find its bootstrap function: _eglMain().
180 _eglOpenLibrary(const char *driverPath
, lib_handle
*handle
)
183 _EGLMain_t mainFunc
= NULL
;
184 const char *error
= "unknown error";
188 _eglLog(_EGL_DEBUG
, "dlopen(%s)", driverPath
);
189 lib
= open_library(driverPath
);
191 #if defined(_EGL_PLATFORM_WINDOWS)
194 mainFunc
= (_EGLMain_t
) GetProcAddress(lib
, "_eglMain");
195 #elif defined(_EGL_PLATFORM_X)
197 mainFunc
= (_EGLMain_t
) dlsym(lib
, "_eglMain");
204 #else /* _EGL_PLATFORM_NO_OS */
205 /* must be the default driver name */
206 if (strcmp(driverPath
, DefaultDriverName
) == 0)
207 mainFunc
= (_EGLMain_t
) _eglMain
;
209 error
= "not builtin driver";
213 _eglLog(_EGL_WARNING
, "Could not open driver %s (%s)",
215 if (!getenv("EGL_DRIVER"))
216 _eglLog(_EGL_WARNING
,
217 "The driver can be overridden by setting EGL_DRIVER");
222 _eglLog(_EGL_WARNING
, "_eglMain not found in %s (%s)",
235 * Load the named driver.
238 _eglLoadDriver(const char *path
, const char *args
)
242 _EGLDriver
*drv
= NULL
;
244 mainFunc
= _eglOpenLibrary(path
, &lib
);
248 drv
= mainFunc(args
);
256 _eglLog(_EGL_WARNING
, "Driver loaded from %s has no name", path
);
257 drv
->Name
= "UNNAMED";
260 drv
->Path
= _eglstrdup(path
);
261 drv
->Args
= (args
) ? _eglstrdup(args
) : NULL
;
262 if (!drv
->Path
|| (args
&& !drv
->Args
)) {
264 free((char *) drv
->Path
);
266 free((char *) drv
->Args
);
273 drv
->LibHandle
= lib
;
280 * Match a display to a preloaded driver.
283 _eglMatchDriver(_EGLDisplay
*dpy
)
285 _EGLDriver
*defaultDriver
= NULL
;
288 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
289 _EGLDriver
*drv
= _eglGlobal
.Drivers
[i
];
291 /* display specifies a driver */
292 if (dpy
->DriverName
) {
293 if (strcmp(dpy
->DriverName
, drv
->Name
) == 0)
296 else if (drv
->Probe
) {
297 if (drv
->Probe(drv
, dpy
))
306 return defaultDriver
;
311 * Load a driver and save it.
314 _eglPreloadDriver(_EGLDisplay
*dpy
)
320 path
= _eglChooseDriver(dpy
, &args
);
324 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
325 drv
= _eglGlobal
.Drivers
[i
];
326 if (strcmp(drv
->Path
, path
) == 0) {
327 _eglLog(_EGL_DEBUG
, "Driver %s is already preloaded",
336 drv
= _eglLoadDriver(path
, args
);
344 _eglGlobal
.Drivers
[_eglGlobal
.NumDrivers
++] = drv
;
351 * Open a preloaded driver.
354 _eglOpenDriver(_EGLDisplay
*dpy
)
356 _EGLDriver
*drv
= _eglMatchDriver(dpy
);
362 * Close a preloaded driver.
365 _eglCloseDriver(_EGLDriver
*drv
, _EGLDisplay
*dpy
)
372 * Preload a user driver.
374 * A user driver can be specified by EGL_DRIVER.
377 _eglPreloadUserDriver(void)
379 #if defined(_EGL_PLATFORM_X) || defined(_EGL_PLATFORM_WINDOWS)
382 const char *suffix
, *p
;
384 env
= getenv("EGL_DRIVER");
389 suffix
= library_suffix();
391 /* append suffix if there isn't */
392 p
= strrchr(path
, '.');
394 size_t len
= strlen(path
);
395 char *tmp
= malloc(len
+ strlen(suffix
) + 2);
397 memcpy(tmp
, path
, len
);
400 strcat(tmp
+ len
, suffix
);
406 drv
= _eglLoadDriver(path
, NULL
);
412 _eglGlobal
.Drivers
[_eglGlobal
.NumDrivers
++] = drv
;
415 #else /* _EGL_PLATFORM_X || _EGL_PLATFORM_WINDOWS */
422 * Preload display drivers.
424 * Display drivers are a set of drivers that support a certain display system.
425 * The display system may be specified by EGL_DISPLAY.
427 * FIXME This makes libEGL a memory hog if an user driver is not specified and
428 * there are many display drivers.
431 _eglPreloadDisplayDrivers(void)
433 #if defined(_EGL_PLATFORM_X)
434 const char *dpy
, *suffix
;
435 char path
[1024], prefix
[32];
437 struct dirent
*dirent
;
439 dpy
= getenv("EGL_DISPLAY");
441 dpy
= _EGL_DEFAULT_DISPLAY
;
445 snprintf(prefix
, sizeof(prefix
), "egl_%s_", dpy
);
446 suffix
= library_suffix();
448 dirp
= opendir(_EGL_DRIVER_SEARCH_DIR
);
452 while ((dirent
= readdir(dirp
))) {
456 /* match the prefix */
457 if (strncmp(dirent
->d_name
, prefix
, strlen(prefix
)) != 0)
460 /* match the suffix */
461 p
= strrchr(dirent
->d_name
, '.');
462 if ((p
&& !suffix
) || (!p
&& suffix
))
464 else if (p
&& suffix
&& strcmp(p
+ 1, suffix
) != 0)
467 snprintf(path
, sizeof(path
),
468 _EGL_DRIVER_SEARCH_DIR
"/%s", dirent
->d_name
);
470 drv
= _eglLoadDriver(path
, NULL
);
472 _eglGlobal
.Drivers
[_eglGlobal
.NumDrivers
++] = drv
;
477 return (_eglGlobal
.NumDrivers
> 0);
478 #else /* _EGL_PLATFORM_X */
485 * Preload the default driver.
488 _eglPreloadDefaultDriver(void)
492 const char *suffix
= library_suffix();
495 snprintf(path
, sizeof(path
), "%s.%s", DefaultDriverName
, suffix
);
497 snprintf(path
, sizeof(path
), DefaultDriverName
);
499 drv
= _eglLoadDriver(path
, NULL
);
503 _eglGlobal
.Drivers
[_eglGlobal
.NumDrivers
++] = drv
;
512 * This function loads the driver modules and creates the corresponding
513 * _EGLDriver objects.
516 _eglPreloadDrivers(void)
520 /* already preloaded */
521 if (_eglGlobal
.NumDrivers
)
524 loaded
= (_eglPreloadUserDriver() ||
525 _eglPreloadDisplayDrivers() ||
526 _eglPreloadDefaultDriver());
533 * Unload preloaded drivers.
536 _eglUnloadDrivers(void)
539 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
540 _EGLDriver
*drv
= _eglGlobal
.Drivers
[i
];
541 lib_handle handle
= drv
->LibHandle
;
544 free((char *) drv
->Path
);
546 free((char *) drv
->Args
);
553 close_library(handle
);
554 _eglGlobal
.Drivers
[i
] = NULL
;
557 _eglGlobal
.NumDrivers
= 0;
562 * Given a display handle, return the _EGLDriver for that display.
565 _eglLookupDriver(EGLDisplay dpy
)
567 _EGLDisplay
*d
= _eglLookupDisplay(dpy
);
576 * Plug all the available fallback routines into the given driver's
580 _eglInitDriverFallbacks(_EGLDriver
*drv
)
582 /* If a pointer is set to NULL, then the device driver _really_ has
585 drv
->API
.Initialize
= NULL
;
586 drv
->API
.Terminate
= NULL
;
588 drv
->API
.GetConfigs
= _eglGetConfigs
;
589 drv
->API
.ChooseConfig
= _eglChooseConfig
;
590 drv
->API
.GetConfigAttrib
= _eglGetConfigAttrib
;
592 drv
->API
.CreateContext
= _eglCreateContext
;
593 drv
->API
.DestroyContext
= _eglDestroyContext
;
594 drv
->API
.MakeCurrent
= _eglMakeCurrent
;
595 drv
->API
.QueryContext
= _eglQueryContext
;
597 drv
->API
.CreateWindowSurface
= _eglCreateWindowSurface
;
598 drv
->API
.CreatePixmapSurface
= _eglCreatePixmapSurface
;
599 drv
->API
.CreatePbufferSurface
= _eglCreatePbufferSurface
;
600 drv
->API
.DestroySurface
= _eglDestroySurface
;
601 drv
->API
.QuerySurface
= _eglQuerySurface
;
602 drv
->API
.SurfaceAttrib
= _eglSurfaceAttrib
;
603 drv
->API
.BindTexImage
= _eglBindTexImage
;
604 drv
->API
.ReleaseTexImage
= _eglReleaseTexImage
;
605 drv
->API
.SwapInterval
= _eglSwapInterval
;
606 drv
->API
.SwapBuffers
= _eglSwapBuffers
;
607 drv
->API
.CopyBuffers
= _eglCopyBuffers
;
609 drv
->API
.QueryString
= _eglQueryString
;
610 drv
->API
.WaitClient
= _eglWaitClient
;
611 drv
->API
.WaitNative
= _eglWaitNative
;
613 #ifdef EGL_MESA_screen_surface
614 drv
->API
.ChooseModeMESA
= _eglChooseModeMESA
;
615 drv
->API
.GetModesMESA
= _eglGetModesMESA
;
616 drv
->API
.GetModeAttribMESA
= _eglGetModeAttribMESA
;
617 drv
->API
.GetScreensMESA
= _eglGetScreensMESA
;
618 drv
->API
.CreateScreenSurfaceMESA
= _eglCreateScreenSurfaceMESA
;
619 drv
->API
.ShowScreenSurfaceMESA
= _eglShowScreenSurfaceMESA
;
620 drv
->API
.ScreenPositionMESA
= _eglScreenPositionMESA
;
621 drv
->API
.QueryScreenMESA
= _eglQueryScreenMESA
;
622 drv
->API
.QueryScreenSurfaceMESA
= _eglQueryScreenSurfaceMESA
;
623 drv
->API
.QueryScreenModeMESA
= _eglQueryScreenModeMESA
;
624 drv
->API
.QueryModeStringMESA
= _eglQueryModeStringMESA
;
625 #endif /* EGL_MESA_screen_surface */
627 #ifdef EGL_VERSION_1_2
628 drv
->API
.CreatePbufferFromClientBuffer
= _eglCreatePbufferFromClientBuffer
;
629 #endif /* EGL_VERSION_1_2 */
635 * Try to determine which EGL APIs (OpenGL, OpenGL ES, OpenVG, etc)
636 * are supported on the system by looking for standard library names.
643 #if defined(_EGL_PLATFORM_WINDOWS)
644 /* XXX not sure about these names */
645 const char *es1_libname
= "libGLESv1_CM.dll";
646 const char *es2_libname
= "libGLESv2.dll";
647 const char *gl_libname
= "OpenGL32.dll";
648 const char *vg_libname
= "libOpenVG.dll";
649 #elif defined(_EGL_PLATFORM_X)
650 const char *es1_libname
= "libGLESv1_CM.so";
651 const char *es2_libname
= "libGLESv2.so";
652 const char *gl_libname
= "libGL.so";
653 const char *vg_libname
= "libOpenVG.so";
654 #else /* _EGL_PLATFORM_NO_OS */
655 const char *es1_libname
= NULL
;
656 const char *es2_libname
= NULL
;
657 const char *gl_libname
= NULL
;
658 const char *vg_libname
= NULL
;
661 if ((lib
= open_library(es1_libname
))) {
663 mask
|= EGL_OPENGL_ES_BIT
;
666 if ((lib
= open_library(es2_libname
))) {
668 mask
|= EGL_OPENGL_ES2_BIT
;
671 if ((lib
= open_library(gl_libname
))) {
673 mask
|= EGL_OPENGL_BIT
;
676 if ((lib
= open_library(vg_libname
))) {
678 mask
|= EGL_OPENVG_BIT
;