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)
29 * Wrappers for dlopen/dlclose()
31 #if defined(_EGL_PLATFORM_WINDOWS)
34 /* XXX Need to decide how to do dynamic name lookup on Windows */
35 static const char DefaultDriverName
[] = "TBD";
37 typedef HMODULE lib_handle
;
40 open_library(const char *filename
)
42 return LoadLibrary(filename
);
46 close_library(HMODULE lib
)
52 #elif defined(_EGL_PLATFORM_X)
55 static const char DefaultDriverName
[] = "egl_softpipe";
57 typedef void * lib_handle
;
60 open_library(const char *filename
)
62 return dlopen(filename
, RTLD_LAZY
);
66 close_library(void *lib
)
71 #else /* _EGL_PLATFORM_NO_OS */
73 static const char DefaultDriverName
[] = "builtin";
75 typedef void *lib_handle
;
78 open_library(const char *filename
)
80 return (void *) filename
;
84 close_library(void *lib
)
93 * Choose a driver for a given display.
94 * The caller may free() the returned strings.
97 _eglChooseDriver(_EGLDisplay
*dpy
, char **argsRet
)
100 const char *args
= NULL
;
101 const char *suffix
= NULL
;
104 path
= getenv("EGL_DRIVER");
106 path
= _eglstrdup(path
);
108 #if defined(_EGL_PLATFORM_X)
109 if (!path
&& dpy
&& dpy
->NativeDisplay
) {
110 /* assume (wrongly!) that the native display is a display string */
111 path
= _eglSplitDisplayString((const char *) dpy
->NativeDisplay
, &args
);
114 #elif defined(_EGL_PLATFORM_WINDOWS)
116 #else /* _EGL_PLATFORM_NO_OS */
118 /* force the use of the default driver */
119 _eglLog(_EGL_DEBUG
, "ignore EGL_DRIVER");
127 path
= _eglstrdup(DefaultDriverName
);
129 /* append suffix if there isn't */
130 p
= strrchr(path
, '.');
132 size_t len
= strlen(path
);
133 char *tmp
= malloc(len
+ strlen(suffix
) + 2);
135 memcpy(tmp
, path
, len
);
138 strcat(tmp
+ len
, suffix
);
146 *argsRet
= (args
) ? _eglstrdup(args
) : NULL
;
153 * Open the named driver and find its bootstrap function: _eglMain().
156 _eglOpenLibrary(const char *driverPath
, lib_handle
*handle
)
159 _EGLMain_t mainFunc
= NULL
;
160 const char *error
= "unknown error";
164 _eglLog(_EGL_DEBUG
, "dlopen(%s)", driverPath
);
165 lib
= open_library(driverPath
);
167 #if defined(_EGL_PLATFORM_WINDOWS)
170 mainFunc
= (_EGLMain_t
) GetProcAddress(lib
, "_eglMain");
171 #elif defined(_EGL_PLATFORM_X)
173 mainFunc
= (_EGLMain_t
) dlsym(lib
, "_eglMain");
180 #else /* _EGL_PLATFORM_NO_OS */
181 /* must be the default driver name */
182 if (strcmp(driverPath
, DefaultDriverName
) == 0)
183 mainFunc
= (_EGLMain_t
) _eglMain
;
185 error
= "not builtin driver";
189 _eglLog(_EGL_WARNING
, "Could not open driver %s (%s)",
191 if (!getenv("EGL_DRIVER"))
192 _eglLog(_EGL_WARNING
,
193 "The driver can be overridden by setting EGL_DRIVER");
198 _eglLog(_EGL_WARNING
, "_eglMain not found in %s (%s)",
211 * Load the named driver. The path and args passed will be
212 * owned by the driver and freed.
215 _eglLoadDriver(char *path
, char *args
)
219 _EGLDriver
*drv
= NULL
;
221 mainFunc
= _eglOpenLibrary(path
, &lib
);
225 drv
= mainFunc(args
);
233 _eglLog(_EGL_WARNING
, "Driver loaded from %s has no name", path
);
234 drv
->Name
= "UNNAMED";
239 drv
->LibHandle
= lib
;
246 * Match a display to a preloaded driver.
249 _eglMatchDriver(_EGLDisplay
*dpy
)
251 _EGLDriver
*defaultDriver
= NULL
;
254 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
255 _EGLDriver
*drv
= _eglGlobal
.Drivers
[i
];
257 /* display specifies a driver */
258 if (dpy
->DriverName
) {
259 if (strcmp(dpy
->DriverName
, drv
->Name
) == 0)
262 else if (drv
->Probe
) {
263 if (drv
->Probe(drv
, dpy
))
272 return defaultDriver
;
277 * Load a driver and save it.
280 _eglPreloadDriver(_EGLDisplay
*dpy
)
286 path
= _eglChooseDriver(dpy
, &args
);
290 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
291 drv
= _eglGlobal
.Drivers
[i
];
292 if (strcmp(drv
->Path
, path
) == 0) {
293 _eglLog(_EGL_DEBUG
, "Driver %s is already preloaded",
302 drv
= _eglLoadDriver(path
, args
);
306 _eglGlobal
.Drivers
[_eglGlobal
.NumDrivers
++] = drv
;
313 * Open a preloaded driver.
316 _eglOpenDriver(_EGLDisplay
*dpy
)
318 _EGLDriver
*drv
= _eglMatchDriver(dpy
);
324 * Close a preloaded driver.
327 _eglCloseDriver(_EGLDriver
*drv
, _EGLDisplay
*dpy
)
334 * Unload preloaded drivers.
337 _eglUnloadDrivers(void)
340 for (i
= 0; i
< _eglGlobal
.NumDrivers
; i
++) {
341 _EGLDriver
*drv
= _eglGlobal
.Drivers
[i
];
342 lib_handle handle
= drv
->LibHandle
;
345 free((char *) drv
->Path
);
347 free((char *) drv
->Args
);
354 close_library(handle
);
355 _eglGlobal
.Drivers
[i
] = NULL
;
358 _eglGlobal
.NumDrivers
= 0;
363 * Given a display handle, return the _EGLDriver for that display.
366 _eglLookupDriver(EGLDisplay dpy
)
368 _EGLDisplay
*d
= _eglLookupDisplay(dpy
);
377 * Plug all the available fallback routines into the given driver's
381 _eglInitDriverFallbacks(_EGLDriver
*drv
)
383 /* If a pointer is set to NULL, then the device driver _really_ has
386 drv
->API
.Initialize
= NULL
;
387 drv
->API
.Terminate
= NULL
;
389 drv
->API
.GetConfigs
= _eglGetConfigs
;
390 drv
->API
.ChooseConfig
= _eglChooseConfig
;
391 drv
->API
.GetConfigAttrib
= _eglGetConfigAttrib
;
393 drv
->API
.CreateContext
= _eglCreateContext
;
394 drv
->API
.DestroyContext
= _eglDestroyContext
;
395 drv
->API
.MakeCurrent
= _eglMakeCurrent
;
396 drv
->API
.QueryContext
= _eglQueryContext
;
398 drv
->API
.CreateWindowSurface
= _eglCreateWindowSurface
;
399 drv
->API
.CreatePixmapSurface
= _eglCreatePixmapSurface
;
400 drv
->API
.CreatePbufferSurface
= _eglCreatePbufferSurface
;
401 drv
->API
.DestroySurface
= _eglDestroySurface
;
402 drv
->API
.QuerySurface
= _eglQuerySurface
;
403 drv
->API
.SurfaceAttrib
= _eglSurfaceAttrib
;
404 drv
->API
.BindTexImage
= _eglBindTexImage
;
405 drv
->API
.ReleaseTexImage
= _eglReleaseTexImage
;
406 drv
->API
.SwapInterval
= _eglSwapInterval
;
407 drv
->API
.SwapBuffers
= _eglSwapBuffers
;
408 drv
->API
.CopyBuffers
= _eglCopyBuffers
;
410 drv
->API
.QueryString
= _eglQueryString
;
411 drv
->API
.WaitClient
= _eglWaitClient
;
412 drv
->API
.WaitNative
= _eglWaitNative
;
414 #ifdef EGL_MESA_screen_surface
415 drv
->API
.ChooseModeMESA
= _eglChooseModeMESA
;
416 drv
->API
.GetModesMESA
= _eglGetModesMESA
;
417 drv
->API
.GetModeAttribMESA
= _eglGetModeAttribMESA
;
418 drv
->API
.GetScreensMESA
= _eglGetScreensMESA
;
419 drv
->API
.CreateScreenSurfaceMESA
= _eglCreateScreenSurfaceMESA
;
420 drv
->API
.ShowScreenSurfaceMESA
= _eglShowScreenSurfaceMESA
;
421 drv
->API
.ScreenPositionMESA
= _eglScreenPositionMESA
;
422 drv
->API
.QueryScreenMESA
= _eglQueryScreenMESA
;
423 drv
->API
.QueryScreenSurfaceMESA
= _eglQueryScreenSurfaceMESA
;
424 drv
->API
.QueryScreenModeMESA
= _eglQueryScreenModeMESA
;
425 drv
->API
.QueryModeStringMESA
= _eglQueryModeStringMESA
;
426 #endif /* EGL_MESA_screen_surface */
428 #ifdef EGL_VERSION_1_2
429 drv
->API
.CreatePbufferFromClientBuffer
= _eglCreatePbufferFromClientBuffer
;
430 #endif /* EGL_VERSION_1_2 */
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
;