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"
24 #if defined(_EGL_PLATFORM_X)
30 * Wrappers for dlopen/dlclose()
32 #if defined(_EGL_PLATFORM_WINDOWS)
35 /* XXX Need to decide how to do dynamic name lookup on Windows */
36 static const char DefaultDriverName[] = "TBD";
38 typedef HMODULE lib_handle;
41 open_library(const char *filename)
43 return LoadLibrary(filename);
47 close_library(HMODULE lib)
53 #elif defined(_EGL_PLATFORM_X)
56 static const char DefaultDriverName[] = "egl_softpipe";
58 typedef void * lib_handle;
61 open_library(const char *filename)
63 return dlopen(filename, RTLD_LAZY);
67 close_library(void *lib)
72 #else /* _EGL_PLATFORM_NO_OS */
74 static const char DefaultDriverName[] = "builtin";
76 typedef void *lib_handle;
79 open_library(const char *filename)
81 return (void *) filename;
85 close_library(void *lib)
94 * Choose a driver for a given display.
95 * The caller may free() the returned strings.
98 _eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
101 const char *args = NULL;
102 const char *suffix = NULL;
105 path = getenv("EGL_DRIVER");
107 path = _eglstrdup(path);
109 #if defined(_EGL_PLATFORM_X)
110 if (!path && dpy && dpy->NativeDisplay) {
111 /* assume (wrongly!) that the native display is a display string */
112 path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args);
115 #elif defined(_EGL_PLATFORM_WINDOWS)
117 #else /* _EGL_PLATFORM_NO_OS */
126 path = _eglstrdup(DefaultDriverName);
128 /* append suffix if there isn't */
129 p = strrchr(path, '.');
131 size_t len = strlen(path);
132 char *tmp = malloc(len + strlen(suffix) + 2);
134 memcpy(tmp, path, len);
137 strcat(tmp + len, suffix);
145 *argsRet = (args) ? _eglstrdup(args) : NULL;
152 * Open the named driver and find its bootstrap function: _eglMain().
155 _eglOpenLibrary(const char *driverPath, lib_handle *handle)
162 #if defined(_EGL_PLATFORM_WINDOWS)
164 _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
165 lib = open_library(driverPath);
167 _eglLog(_EGL_WARNING, "Could not open %s",
171 mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
172 #elif defined(_EGL_PLATFORM_X)
173 _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
174 lib = open_library(driverPath);
176 _eglLog(_EGL_WARNING, "Could not open %s (%s)",
177 driverPath, dlerror());
178 if (!getenv("EGL_DRIVER"))
179 _eglLog(_EGL_WARNING,
180 "The driver can be overridden by setting EGL_DRIVER");
183 mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
184 #else /* _EGL_PLATFORM_NO_OS */
186 /* must be default driver name */
187 if (strcmp(driverPath, DefaultDriverName) == 0)
188 mainFunc = (_EGLMain_t) _eglMain;
194 _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverPath);
206 * Load the named driver. The path and args passed will be
207 * owned by the driver and freed.
210 _eglLoadDriver(char *path, char *args)
214 _EGLDriver *drv = NULL;
216 mainFunc = _eglOpenLibrary(path, &lib);
220 drv = mainFunc(args);
228 _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path);
229 drv->Name = "UNNAMED";
234 drv->LibHandle = lib;
241 * Match a display to a preloaded driver.
244 _eglMatchDriver(_EGLDisplay *dpy)
246 _EGLDriver *defaultDriver = NULL;
249 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
250 _EGLDriver *drv = _eglGlobal.Drivers[i];
252 /* display specifies a driver */
253 if (dpy->DriverName) {
254 if (strcmp(dpy->DriverName, drv->Name) == 0)
257 else if (drv->Probe) {
258 if (drv->Probe(drv, dpy))
267 return defaultDriver;
272 * Load a driver and save it.
275 _eglPreloadDriver(_EGLDisplay *dpy)
281 path = _eglChooseDriver(dpy, &args);
285 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
286 drv = _eglGlobal.Drivers[i];
287 if (strcmp(drv->Path, path) == 0) {
288 _eglLog(_EGL_DEBUG, "Driver %s is already preloaded",
297 drv = _eglLoadDriver(path, args);
301 _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
308 * Open a preloaded driver.
311 _eglOpenDriver(_EGLDisplay *dpy)
313 _EGLDriver *drv = _eglMatchDriver(dpy);
319 * Close a preloaded driver.
322 _eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy)
329 * Unload preloaded drivers.
332 _eglUnloadDrivers(void)
335 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
336 _EGLDriver *drv = _eglGlobal.Drivers[i];
337 lib_handle handle = drv->LibHandle;
340 free((char *) drv->Path);
342 free((char *) drv->Args);
349 close_library(handle);
350 _eglGlobal.Drivers[i] = NULL;
353 _eglGlobal.NumDrivers = 0;
358 * Given a display handle, return the _EGLDriver for that display.
361 _eglLookupDriver(EGLDisplay dpy)
363 _EGLDisplay *d = _eglLookupDisplay(dpy);
372 * Plug all the available fallback routines into the given driver's
376 _eglInitDriverFallbacks(_EGLDriver *drv)
378 /* If a pointer is set to NULL, then the device driver _really_ has
381 drv->API.Initialize = NULL;
382 drv->API.Terminate = NULL;
384 drv->API.GetConfigs = _eglGetConfigs;
385 drv->API.ChooseConfig = _eglChooseConfig;
386 drv->API.GetConfigAttrib = _eglGetConfigAttrib;
388 drv->API.CreateContext = _eglCreateContext;
389 drv->API.DestroyContext = _eglDestroyContext;
390 drv->API.MakeCurrent = _eglMakeCurrent;
391 drv->API.QueryContext = _eglQueryContext;
393 drv->API.CreateWindowSurface = _eglCreateWindowSurface;
394 drv->API.CreatePixmapSurface = _eglCreatePixmapSurface;
395 drv->API.CreatePbufferSurface = _eglCreatePbufferSurface;
396 drv->API.DestroySurface = _eglDestroySurface;
397 drv->API.QuerySurface = _eglQuerySurface;
398 drv->API.SurfaceAttrib = _eglSurfaceAttrib;
399 drv->API.BindTexImage = _eglBindTexImage;
400 drv->API.ReleaseTexImage = _eglReleaseTexImage;
401 drv->API.SwapInterval = _eglSwapInterval;
402 drv->API.SwapBuffers = _eglSwapBuffers;
403 drv->API.CopyBuffers = _eglCopyBuffers;
405 drv->API.QueryString = _eglQueryString;
406 drv->API.WaitGL = _eglWaitGL;
407 drv->API.WaitNative = _eglWaitNative;
409 #ifdef EGL_MESA_screen_surface
410 drv->API.ChooseModeMESA = _eglChooseModeMESA;
411 drv->API.GetModesMESA = _eglGetModesMESA;
412 drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
413 drv->API.GetScreensMESA = _eglGetScreensMESA;
414 drv->API.CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
415 drv->API.ShowScreenSurfaceMESA = _eglShowScreenSurfaceMESA;
416 drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
417 drv->API.QueryScreenMESA = _eglQueryScreenMESA;
418 drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
419 drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
420 drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
421 #endif /* EGL_MESA_screen_surface */
423 #ifdef EGL_VERSION_1_2
424 drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
425 #endif /* EGL_VERSION_1_2 */
427 #ifdef EGL_KHR_image_base
428 drv->API.CreateImageKHR = _eglCreateImageKHR;
429 drv->API.DestroyImageKHR = _eglDestroyImageKHR;
430 #endif /* EGL_KHR_image_base */
436 * Try to determine which EGL APIs (OpenGL, OpenGL ES, OpenVG, etc)
437 * are supported on the system by looking for standard library names.
444 #if defined(_EGL_PLATFORM_WINDOWS)
445 /* XXX not sure about these names */
446 const char *es1_libname = "libGLESv1_CM.dll";
447 const char *es2_libname = "libGLESv2.dll";
448 const char *gl_libname = "OpenGL32.dll";
449 const char *vg_libname = "libOpenVG.dll";
450 #elif defined(_EGL_PLATFORM_X)
451 const char *es1_libname = "libGLESv1_CM.so";
452 const char *es2_libname = "libGLESv2.so";
453 const char *gl_libname = "libGL.so";
454 const char *vg_libname = "libOpenVG.so";
455 #else /* _EGL_PLATFORM_NO_OS */
456 const char *es1_libname = NULL;
457 const char *es2_libname = NULL;
458 const char *gl_libname = NULL;
459 const char *vg_libname = NULL;
462 if ((lib = open_library(es1_libname))) {
464 mask |= EGL_OPENGL_ES_BIT;
467 if ((lib = open_library(es2_libname))) {
469 mask |= EGL_OPENGL_ES2_BIT;
472 if ((lib = open_library(gl_libname))) {
474 mask |= EGL_OPENGL_BIT;
477 if ((lib = open_library(vg_libname))) {
479 mask |= EGL_OPENVG_BIT;