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 #elif defined(_EGL_PLATFORM_WINDOWS)
26 /* Use static linking on Windows for now */
27 #define WINDOWS_STATIC_LINK
31 * Wrappers for dlopen/dlclose()
33 #if defined(_EGL_PLATFORM_WINDOWS)
34 #ifdef WINDOWS_STATIC_LINK
35 static const char *DefaultDriverName = "Windows EGL Static Library";
37 /* XXX Need to decide how to do dynamic name lookup on Windows */
38 static const char *DefaultDriverName = "TBD";
40 typedef HMODULE lib_handle;
43 open_library(const char *filename)
45 #ifdef WINDOWS_STATIC_LINK
48 return LoadLibrary(filename);
53 close_library(HMODULE lib)
55 #ifdef WINDOWS_STATIC_LINK
61 #elif defined(_EGL_PLATFORM_X)
62 static const char *DefaultDriverName = "egl_softpipe";
64 typedef void * lib_handle;
67 open_library(const char *filename)
69 return dlopen(filename, RTLD_LAZY);
73 close_library(void *lib)
82 * Choose a driver for a given display.
83 * The caller may free() the returned strings.
86 _eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
89 const char *args = NULL;
90 const char *suffix = NULL;
93 path = getenv("EGL_DRIVER");
95 path = _eglstrdup(path);
97 #if defined(_EGL_PLATFORM_X)
98 if (!path && dpy->NativeDisplay) {
99 /* assume (wrongly!) that the native display is a display string */
100 path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args);
103 #elif defined(_EGL_PLATFORM_WINDOWS)
105 #endif /* _EGL_PLATFORM_X */
108 path = _eglstrdup(DefaultDriverName);
110 /* append suffix if there isn't */
111 p = strrchr(path, '.');
113 size_t len = strlen(path);
114 char *tmp = malloc(len + strlen(suffix) + 2);
116 memcpy(tmp, path, len);
119 strcat(tmp + len, suffix);
127 *argsRet = (args) ? _eglstrdup(args) : NULL;
134 * Open the named driver and find its bootstrap function: _eglMain().
137 _eglOpenLibrary(const char *driverPath, lib_handle *handle)
144 #if defined(_EGL_PLATFORM_WINDOWS)
145 /* Use static linking on Windows for now */
146 #ifdef WINDOWS_STATIC_LINK
148 mainFunc = (_EGLMain_t)_eglMain;
151 _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
152 lib = open_library(driverPath);
154 _eglLog(_EGL_WARNING, "Could not open %s",
158 mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
160 #elif defined(_EGL_PLATFORM_X)
161 _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
162 lib = open_library(driverPath);
164 _eglLog(_EGL_WARNING, "Could not open %s (%s)",
165 driverPath, dlerror());
166 if (!getenv("EGL_DRIVER"))
167 _eglLog(_EGL_WARNING,
168 "The driver can be overridden by setting EGL_DRIVER");
171 mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
175 _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverPath);
187 * Load the named driver. The path and args passed will be
188 * owned by the driver and freed.
191 _eglLoadDriver(char *path, char *args)
195 _EGLDriver *drv = NULL;
197 mainFunc = _eglOpenLibrary(path, &lib);
201 drv = mainFunc(args);
209 _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path);
210 drv->Name = "UNNAMED";
215 drv->LibHandle = lib;
222 * Match a display to a preloaded driver.
225 _eglMatchDriver(_EGLDisplay *dpy)
227 _EGLDriver *defaultDriver = NULL;
230 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
231 _EGLDriver *drv = _eglGlobal.Drivers[i];
233 /* display specifies a driver */
234 if (dpy->DriverName) {
235 if (strcmp(dpy->DriverName, drv->Name) == 0)
238 else if (drv->Probe) {
239 if (drv->Probe(drv, dpy))
248 return defaultDriver;
253 * Load a driver and save it.
256 _eglPreloadDriver(_EGLDisplay *dpy)
262 path = _eglChooseDriver(dpy, &args);
266 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
267 drv = _eglGlobal.Drivers[i];
268 if (strcmp(drv->Path, path) == 0) {
269 _eglLog(_EGL_DEBUG, "Driver %s is already preloaded",
278 drv = _eglLoadDriver(path, args);
282 _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
289 * Open a preloaded driver.
292 _eglOpenDriver(_EGLDisplay *dpy)
294 _EGLDriver *drv = _eglMatchDriver(dpy);
300 * Close a preloaded driver.
303 _eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy)
310 * Unload preloaded drivers.
313 _eglUnloadDrivers(void)
316 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
317 _EGLDriver *drv = _eglGlobal.Drivers[i];
318 lib_handle handle = drv->LibHandle;
321 free((char *) drv->Path);
323 free((char *) drv->Args);
330 close_library(handle);
331 _eglGlobal.Drivers[i] = NULL;
334 _eglGlobal.NumDrivers = 0;
339 * Given a display handle, return the _EGLDriver for that display.
342 _eglLookupDriver(EGLDisplay dpy)
344 _EGLDisplay *d = _eglLookupDisplay(dpy);
353 * Plug all the available fallback routines into the given driver's
357 _eglInitDriverFallbacks(_EGLDriver *drv)
359 /* If a pointer is set to NULL, then the device driver _really_ has
362 drv->API.Initialize = NULL;
363 drv->API.Terminate = NULL;
365 drv->API.GetConfigs = _eglGetConfigs;
366 drv->API.ChooseConfig = _eglChooseConfig;
367 drv->API.GetConfigAttrib = _eglGetConfigAttrib;
369 drv->API.CreateContext = _eglCreateContext;
370 drv->API.DestroyContext = _eglDestroyContext;
371 drv->API.MakeCurrent = _eglMakeCurrent;
372 drv->API.QueryContext = _eglQueryContext;
374 drv->API.CreateWindowSurface = _eglCreateWindowSurface;
375 drv->API.CreatePixmapSurface = _eglCreatePixmapSurface;
376 drv->API.CreatePbufferSurface = _eglCreatePbufferSurface;
377 drv->API.DestroySurface = _eglDestroySurface;
378 drv->API.QuerySurface = _eglQuerySurface;
379 drv->API.SurfaceAttrib = _eglSurfaceAttrib;
380 drv->API.BindTexImage = _eglBindTexImage;
381 drv->API.ReleaseTexImage = _eglReleaseTexImage;
382 drv->API.SwapInterval = _eglSwapInterval;
383 drv->API.SwapBuffers = _eglSwapBuffers;
384 drv->API.CopyBuffers = _eglCopyBuffers;
386 drv->API.QueryString = _eglQueryString;
387 drv->API.WaitGL = _eglWaitGL;
388 drv->API.WaitNative = _eglWaitNative;
390 #ifdef EGL_MESA_screen_surface
391 drv->API.ChooseModeMESA = _eglChooseModeMESA;
392 drv->API.GetModesMESA = _eglGetModesMESA;
393 drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
394 drv->API.GetScreensMESA = _eglGetScreensMESA;
395 drv->API.CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
396 drv->API.ShowScreenSurfaceMESA = _eglShowScreenSurfaceMESA;
397 drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
398 drv->API.QueryScreenMESA = _eglQueryScreenMESA;
399 drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
400 drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
401 drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
402 #endif /* EGL_MESA_screen_surface */
404 #ifdef EGL_VERSION_1_2
405 drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
406 #endif /* EGL_VERSION_1_2 */
412 * Try to determine which EGL APIs (OpenGL, OpenGL ES, OpenVG, etc)
413 * are supported on the system by looking for standard library names.
420 #if defined(_EGL_PLATFORM_WINDOWS)
421 /* XXX not sure about these names */
422 const char *es1_libname = "libGLESv1_CM.dll";
423 const char *es2_libname = "libGLESv2.dll";
424 const char *gl_libname = "OpenGL32.dll";
425 const char *vg_libname = "libOpenVG.dll";
426 #elif defined(_EGL_PLATFORM_X)
427 const char *es1_libname = "libGLESv1_CM.so";
428 const char *es2_libname = "libGLESv2.so";
429 const char *gl_libname = "libGL.so";
430 const char *vg_libname = "libOpenVG.so";
433 if ((lib = open_library(es1_libname))) {
435 mask |= EGL_OPENGL_ES_BIT;
438 if ((lib = open_library(es2_libname))) {
440 mask |= EGL_OPENGL_ES2_BIT;
443 if ((lib = open_library(gl_libname))) {
445 mask |= EGL_OPENGL_BIT;
448 if ((lib = open_library(vg_libname))) {
450 mask |= EGL_OPENVG_BIT;