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)
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 typedef HMODULE lib_handle;
44 open_library(const char *filename)
46 #ifdef WINDOWS_STATIC_LINK
49 return LoadLibrary(filename);
54 close_library(HMODULE lib)
56 #ifdef WINDOWS_STATIC_LINK
62 #elif defined(_EGL_PLATFORM_X)
63 static const char *DefaultDriverName = "egl_softpipe";
65 typedef void * lib_handle;
68 open_library(const char *filename)
70 return dlopen(filename, RTLD_LAZY);
74 close_library(void *lib)
83 * Choose a driver for a given display.
84 * The caller may free() the returned strings.
87 _eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
90 const char *args = NULL;
91 const char *suffix = NULL;
94 path = getenv("EGL_DRIVER");
96 path = _eglstrdup(path);
98 #if defined(_EGL_PLATFORM_X)
99 if (!path && dpy->NativeDisplay) {
100 /* assume (wrongly!) that the native display is a display string */
101 path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args);
104 #elif defined(_EGL_PLATFORM_WINDOWS)
106 #endif /* _EGL_PLATFORM_X */
109 path = _eglstrdup(DefaultDriverName);
111 /* append suffix if there isn't */
112 p = strrchr(path, '.');
114 size_t len = strlen(path);
115 char *tmp = malloc(len + strlen(suffix) + 2);
117 memcpy(tmp, path, len);
120 strcat(tmp + len, suffix);
128 *argsRet = (args) ? _eglstrdup(args) : NULL;
135 * Open the named driver and find its bootstrap function: _eglMain().
138 _eglOpenLibrary(const char *driverPath, lib_handle *handle)
145 #if defined(_EGL_PLATFORM_WINDOWS)
146 /* Use static linking on Windows for now */
147 #ifdef WINDOWS_STATIC_LINK
149 mainFunc = (_EGLMain_t)_eglMain;
152 _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
153 lib = open_library(driverPath);
155 _eglLog(_EGL_WARNING, "Could not open %s",
159 mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
161 #elif defined(_EGL_PLATFORM_X)
162 _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
163 lib = open_library(driverPath);
165 _eglLog(_EGL_WARNING, "Could not open %s (%s)",
166 driverPath, dlerror());
167 if (!getenv("EGL_DRIVER"))
168 _eglLog(_EGL_WARNING,
169 "The driver can be overridden by setting EGL_DRIVER");
172 mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
176 _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverPath);
188 * Load the named driver. The path and args passed will be
189 * owned by the driver and freed.
192 _eglLoadDriver(char *path, char *args)
196 _EGLDriver *drv = NULL;
199 (void) _eglOpenLibrary;
201 lib = (lib_handle) 0;
206 drv = mainFunc(args);
214 _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path);
215 drv->Name = "UNNAMED";
220 drv->LibHandle = lib;
227 * Match a display to a preloaded driver.
230 _eglMatchDriver(_EGLDisplay *dpy)
232 _EGLDriver *defaultDriver = NULL;
235 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
236 _EGLDriver *drv = _eglGlobal.Drivers[i];
238 /* display specifies a driver */
239 if (dpy->DriverName) {
240 if (strcmp(dpy->DriverName, drv->Name) == 0)
243 else if (drv->Probe) {
244 if (drv->Probe(drv, dpy))
253 return defaultDriver;
258 * Load a driver and save it.
261 _eglPreloadDriver(_EGLDisplay *dpy)
267 path = _eglChooseDriver(dpy, &args);
271 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
272 drv = _eglGlobal.Drivers[i];
273 if (strcmp(drv->Path, path) == 0) {
274 _eglLog(_EGL_DEBUG, "Driver %s is already preloaded",
283 drv = _eglLoadDriver(path, args);
287 _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
294 * Open a preloaded driver.
297 _eglOpenDriver(_EGLDisplay *dpy)
299 _EGLDriver *drv = _eglMatchDriver(dpy);
305 * Close a preloaded driver.
308 _eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy)
315 * Unload preloaded drivers.
318 _eglUnloadDrivers(void)
321 for (i = 0; i < _eglGlobal.NumDrivers; i++) {
322 _EGLDriver *drv = _eglGlobal.Drivers[i];
323 lib_handle handle = drv->LibHandle;
326 free((char *) drv->Path);
328 free((char *) drv->Args);
335 close_library(handle);
336 _eglGlobal.Drivers[i] = NULL;
339 _eglGlobal.NumDrivers = 0;
344 * Given a display handle, return the _EGLDriver for that display.
347 _eglLookupDriver(EGLDisplay dpy)
349 _EGLDisplay *d = _eglLookupDisplay(dpy);
358 * Plug all the available fallback routines into the given driver's
362 _eglInitDriverFallbacks(_EGLDriver *drv)
364 /* If a pointer is set to NULL, then the device driver _really_ has
367 drv->API.Initialize = NULL;
368 drv->API.Terminate = NULL;
370 drv->API.GetConfigs = _eglGetConfigs;
371 drv->API.ChooseConfig = _eglChooseConfig;
372 drv->API.GetConfigAttrib = _eglGetConfigAttrib;
374 drv->API.CreateContext = _eglCreateContext;
375 drv->API.DestroyContext = _eglDestroyContext;
376 drv->API.MakeCurrent = _eglMakeCurrent;
377 drv->API.QueryContext = _eglQueryContext;
379 drv->API.CreateWindowSurface = _eglCreateWindowSurface;
380 drv->API.CreatePixmapSurface = _eglCreatePixmapSurface;
381 drv->API.CreatePbufferSurface = _eglCreatePbufferSurface;
382 drv->API.DestroySurface = _eglDestroySurface;
383 drv->API.QuerySurface = _eglQuerySurface;
384 drv->API.SurfaceAttrib = _eglSurfaceAttrib;
385 drv->API.BindTexImage = _eglBindTexImage;
386 drv->API.ReleaseTexImage = _eglReleaseTexImage;
387 drv->API.SwapInterval = _eglSwapInterval;
388 drv->API.SwapBuffers = _eglSwapBuffers;
389 drv->API.CopyBuffers = _eglCopyBuffers;
391 drv->API.QueryString = _eglQueryString;
392 drv->API.WaitGL = _eglWaitGL;
393 drv->API.WaitNative = _eglWaitNative;
395 #ifdef EGL_MESA_screen_surface
396 drv->API.ChooseModeMESA = _eglChooseModeMESA;
397 drv->API.GetModesMESA = _eglGetModesMESA;
398 drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
399 drv->API.GetScreensMESA = _eglGetScreensMESA;
400 drv->API.CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
401 drv->API.ShowScreenSurfaceMESA = _eglShowScreenSurfaceMESA;
402 drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
403 drv->API.QueryScreenMESA = _eglQueryScreenMESA;
404 drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
405 drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
406 drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
407 #endif /* EGL_MESA_screen_surface */
409 #ifdef EGL_VERSION_1_2
410 drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
411 #endif /* EGL_VERSION_1_2 */
413 #ifdef EGL_KHR_image_base
414 drv->API.CreateImageKHR = _eglCreateImageKHR;
415 drv->API.DestroyImageKHR = _eglDestroyImageKHR;
416 #endif /* EGL_KHR_image_base */
422 * Try to determine which EGL APIs (OpenGL, OpenGL ES, OpenVG, etc)
423 * are supported on the system by looking for standard library names.
430 #if defined(_EGL_PLATFORM_WINDOWS)
431 /* XXX not sure about these names */
432 const char *es1_libname = "libGLESv1_CM.dll";
433 const char *es2_libname = "libGLESv2.dll";
434 const char *gl_libname = "OpenGL32.dll";
435 const char *vg_libname = "libOpenVG.dll";
436 #elif defined(_EGL_PLATFORM_X)
437 const char *es1_libname = "libGLESv1_CM.so";
438 const char *es2_libname = "libGLESv2.so";
439 const char *gl_libname = "libGL.so";
440 const char *vg_libname = "libOpenVG.so";
443 if ((lib = open_library(es1_libname))) {
445 mask |= EGL_OPENGL_ES_BIT;
448 if ((lib = open_library(es2_libname))) {
450 mask |= EGL_OPENGL_ES2_BIT;
453 if ((lib = open_library(gl_libname))) {
455 mask |= EGL_OPENGL_BIT;
458 if ((lib = open_library(vg_libname))) {
460 mask |= EGL_OPENVG_BIT;