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)
26 #elif defined(_EGL_PLATFORM_WINDOWS)
27 /* Use static linking on Windows for now */
28 #define WINDOWS_STATIC_LINK
32 * Wrappers for dlopen/dlclose()
34 #if defined(_EGL_PLATFORM_WINDOWS)
35 #ifdef WINDOWS_STATIC_LINK
36 static const char *DefaultDriverName = "Windows EGL Static Library";
38 /* XXX Need to decide how to do dynamic name lookup on Windows */
39 static const char *DefaultDriverName = "TBD";
41 static const char *SysFS = NULL;
42 typedef HMODULE lib_handle;
45 open_library(const char *filename)
47 #ifdef WINDOWS_STATIC_LINK
50 return LoadLibrary(filename);
55 close_library(HMODULE lib)
57 #ifdef WINDOWS_STATIC_LINK
63 #elif defined(_EGL_PLATFORM_X)
64 static const char *DefaultDriverName = ":0";
65 static const char *SysFS = "/sys/class";
67 typedef void * lib_handle;
70 open_library(const char *filename)
72 return dlopen(filename, RTLD_LAZY);
76 close_library(void *lib)
84 * Given a card number, use sysfs to determine the DRI driver name.
87 _eglChooseDRMDriver(int card)
90 return _eglstrdup("libEGLdri");
92 char path[2000], driverName[2000];
96 snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", SysFS, card);
102 fgets(driverName, sizeof(driverName), f);
105 if ((length = strlen(driverName)) > 1) {
106 /* remove the trailing newline from sysfs */
107 driverName[length - 1] = '\0';
108 strncat(driverName, "_dri", sizeof(driverName));
109 return _eglstrdup(driverName);
119 * XXX this function is totally subject change!!!
122 * Determine/return the path of the driver to use for the given native display.
124 * Try to be clever and determine if nativeDisplay is an Xlib Display
125 * ptr or a string (naming a driver or screen number, etc).
127 * If the first character is ':' we interpret it as a screen or card index
128 * number (i.e. ":0" or ":1", etc)
129 * Else if the first character is '!' we interpret it as specific driver name
130 * (i.e. "!r200" or "!i830".
132 * Whatever follows ':' is interpreted as arguments.
134 * The caller may free() the returned strings.
137 _eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
140 const char *args = NULL;
142 path = getenv("EGL_DRIVER");
144 path = _eglstrdup(path);
146 #if defined(_EGL_PLATFORM_X)
147 (void) DefaultDriverName;
149 if (!path && dpy->NativeDisplay) {
150 const char *dpyString = (const char *) dpy->NativeDisplay;
152 /* parse the display string */
153 if (dpyString[0] == '!' || dpyString[0] == ':') {
154 if (dpyString[0] == '!') {
155 path = _eglstrdup(dpyString);
156 p = strchr(path, ':');
160 p = strchr(dpyString, ':');
166 if (!path && p[0] >= '0' && p[0] <= '9' && !p[1]) {
168 path = (char *) _eglChooseDRMDriver(card);
174 path = (char *) _xeglChooseDriver(dpy);
177 #elif defined(_EGL_PLATFORM_WINDOWS)
179 path = _eglstrdup(DefaultDriverName);
180 #endif /* _EGL_PLATFORM_X */
183 *argsRet = (args) ? _eglstrdup(args) : NULL;
190 * Open the named driver and find its bootstrap function: _eglMain().
193 _eglOpenLibrary(const char *driverName, lib_handle *handle)
197 char driverFilename[1000];
201 #if defined(_EGL_PLATFORM_WINDOWS)
202 /* Use static linking on Windows for now */
203 #ifdef WINDOWS_STATIC_LINK
205 mainFunc = (_EGLMain_t)_eglMain;
208 sprintf(driverFilename, "%s.dll", driverName);
209 _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
210 lib = open_library(driverFilename);
212 _eglLog(_EGL_WARNING, "Could not open %s",
216 mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
218 #elif defined(_EGL_PLATFORM_X)
219 /* XXX also prepend a directory path??? */
220 sprintf(driverFilename, "%s.so", driverName);
221 _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
222 lib = open_library(driverFilename);
224 _eglLog(_EGL_WARNING, "Could not open %s (%s)",
225 driverFilename, dlerror());
228 mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
232 _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
244 * Load the named driver. The path and args passed will be
245 * owned by the driver and freed.
248 _eglLoadDriver(char *path, char *args)
252 _EGLDriver *drv = NULL;
254 mainFunc = _eglOpenLibrary(path, &lib);
258 drv = mainFunc(args);
266 _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path);
267 drv->Name = "UNNAMED";
272 drv->LibHandle = lib;
279 * Match a display to a preloaded driver.
282 _eglMatchDriver(_EGLDisplay *dpy)
284 _EGLDriver *defaultDriver = NULL;
287 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
288 _EGLDriver *drv = _eglGlobal.Drivers[i];
290 /* display specifies a driver */
291 if (dpy->DriverName) {
292 if (strcmp(dpy->DriverName, drv->Name) == 0)
295 else if (drv->Probe) {
296 if (drv->Probe(drv, dpy))
305 return defaultDriver;
310 * Load a driver and save it.
313 _eglPreloadDriver(_EGLDisplay *dpy)
319 path = _eglChooseDriver(dpy, &args);
323 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
324 drv = _eglGlobal.Drivers[i];
325 if (strcmp(drv->Path, path) == 0) {
326 _eglLog(_EGL_DEBUG, "Driver %s is already preloaded",
335 drv = _eglLoadDriver(path, args);
339 _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
346 * Open a preloaded driver.
349 _eglOpenDriver(_EGLDisplay *dpy)
351 _EGLDriver *drv = _eglMatchDriver(dpy);
357 * Close a preloaded driver.
360 _eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy)
367 * Unload preloaded drivers.
370 _eglUnloadDrivers(void)
373 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
374 _EGLDriver *drv = _eglGlobal.Drivers[i];
375 lib_handle handle = drv->LibHandle;
378 free((char *) drv->Path);
380 free((char *) drv->Args);
387 close_library(handle);
388 _eglGlobal.Drivers[i] = NULL;
391 _eglGlobal.NumDrivers = 0;
396 * Given a display handle, return the _EGLDriver for that display.
399 _eglLookupDriver(EGLDisplay dpy)
401 _EGLDisplay *d = _eglLookupDisplay(dpy);
410 * Plug all the available fallback routines into the given driver's
414 _eglInitDriverFallbacks(_EGLDriver *drv)
416 /* If a pointer is set to NULL, then the device driver _really_ has
419 drv->API.Initialize = NULL;
420 drv->API.Terminate = NULL;
422 drv->API.GetConfigs = _eglGetConfigs;
423 drv->API.ChooseConfig = _eglChooseConfig;
424 drv->API.GetConfigAttrib = _eglGetConfigAttrib;
426 drv->API.CreateContext = _eglCreateContext;
427 drv->API.DestroyContext = _eglDestroyContext;
428 drv->API.MakeCurrent = _eglMakeCurrent;
429 drv->API.QueryContext = _eglQueryContext;
431 drv->API.CreateWindowSurface = _eglCreateWindowSurface;
432 drv->API.CreatePixmapSurface = _eglCreatePixmapSurface;
433 drv->API.CreatePbufferSurface = _eglCreatePbufferSurface;
434 drv->API.DestroySurface = _eglDestroySurface;
435 drv->API.QuerySurface = _eglQuerySurface;
436 drv->API.SurfaceAttrib = _eglSurfaceAttrib;
437 drv->API.BindTexImage = _eglBindTexImage;
438 drv->API.ReleaseTexImage = _eglReleaseTexImage;
439 drv->API.SwapInterval = _eglSwapInterval;
440 drv->API.SwapBuffers = _eglSwapBuffers;
441 drv->API.CopyBuffers = _eglCopyBuffers;
443 drv->API.QueryString = _eglQueryString;
444 drv->API.WaitGL = _eglWaitGL;
445 drv->API.WaitNative = _eglWaitNative;
447 #ifdef EGL_MESA_screen_surface
448 drv->API.ChooseModeMESA = _eglChooseModeMESA;
449 drv->API.GetModesMESA = _eglGetModesMESA;
450 drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
451 drv->API.GetScreensMESA = _eglGetScreensMESA;
452 drv->API.CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
453 drv->API.ShowScreenSurfaceMESA = _eglShowScreenSurfaceMESA;
454 drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
455 drv->API.QueryScreenMESA = _eglQueryScreenMESA;
456 drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
457 drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
458 drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
459 #endif /* EGL_MESA_screen_surface */
461 #ifdef EGL_VERSION_1_2
462 drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
463 #endif /* EGL_VERSION_1_2 */
469 * Try to determine which EGL APIs (OpenGL, OpenGL ES, OpenVG, etc)
470 * are supported on the system by looking for standard library names.
477 #if defined(_EGL_PLATFORM_WINDOWS)
478 /* XXX not sure about these names */
479 const char *es1_libname = "libGLESv1_CM.dll";
480 const char *es2_libname = "libGLESv2.dll";
481 const char *gl_libname = "OpenGL32.dll";
482 const char *vg_libname = "libOpenVG.dll";
483 #elif defined(_EGL_PLATFORM_X)
484 const char *es1_libname = "libGLESv1_CM.so";
485 const char *es2_libname = "libGLESv2.so";
486 const char *gl_libname = "libGL.so";
487 const char *vg_libname = "libOpenVG.so";
490 if ((lib = open_library(es1_libname))) {
492 mask |= EGL_OPENGL_ES_BIT;
495 if ((lib = open_library(es2_libname))) {
497 mask |= EGL_OPENGL_ES2_BIT;
500 if ((lib = open_library(gl_libname))) {
502 mask |= EGL_OPENGL_BIT;
505 if ((lib = open_library(vg_libname))) {
507 mask |= EGL_OPENVG_BIT;