2 * Functions for choosing and opening/loading device drivers.
11 #include "eglconfig.h"
12 #include "eglcontext.h"
13 #include "egldefines.h"
14 #include "egldisplay.h"
15 #include "egldriver.h"
16 #include "eglglobals.h"
20 #include "eglscreen.h"
21 #include "eglstring.h"
22 #include "eglsurface.h"
24 #if defined(_EGL_PLATFORM_X)
26 #elif defined(_EGL_PLATFORM_WINDOWS)
28 #elif defined(_EGL_PLATFORM_WINCE)
33 const char *DefaultDriverName = ":0";
34 const char *SysFS = "/sys/class";
40 * Given a card number, use sysfs to determine the DRI driver name.
43 _eglChooseDRMDriver(int card)
46 return _eglstrdup("libEGLdri");
48 char path[2000], driverName[2000];
52 snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", SysFS, card);
58 fgets(driverName, sizeof(driverName), f);
61 if ((length = strlen(driverName)) > 1) {
62 /* remove the trailing newline from sysfs */
63 driverName[length - 1] = '\0';
64 strncat(driverName, "_dri", sizeof(driverName));
65 return _eglstrdup(driverName);
75 * Determine/return the name of the driver to use for the given _EGLDisplay.
77 * Try to be clever and determine if nativeDisplay is an Xlib Display
78 * ptr or a string (naming a driver or screen number, etc).
80 * If the first character is ':' we interpret it as a screen or card index
81 * number (i.e. ":0" or ":1", etc)
82 * Else if the first character is '!' we interpret it as specific driver name
83 * (i.e. "!r200" or "!i830".
85 * Whatever follows ':' is copied and put into dpy->DriverArgs.
87 * The caller may free() the returned string.
90 _eglChooseDriver(_EGLDisplay *dpy)
92 const char *displayString = (const char *) dpy->NativeDisplay;
93 const char *driverName = NULL;
96 /* choose a default */
97 displayString = DefaultDriverName;
100 /* extract default DriverArgs = whatever follows ':' */
101 if (displayString[0] == '!' ||
102 displayString[0] == ':') {
103 const char *args = strchr(displayString, ':');
105 dpy->DriverArgs = _eglstrdup(args + 1);
108 /* determine driver name now */
109 if (displayString && displayString[0] == ':' &&
110 (displayString[1] >= '0' && displayString[1] <= '9') &&
112 int card = atoi(displayString + 1);
113 driverName = _eglChooseDRMDriver(card);
115 else if (displayString && displayString[0] == '!') {
116 /* use user-specified driver name */
117 driverName = _eglstrdup(displayString + 1);
118 /* truncate driverName at ':' if present */
120 char *args = strchr(driverName, ':');
127 /* NativeDisplay is not a string! */
128 #if defined(_EGL_PLATFORM_X)
129 driverName = _xeglChooseDriver(dpy);
130 #elif defined(_EGL_PLATFORM_WINDOWS)
132 driverName = _weglChooseDriver(dpy);
133 #elif defined(_EGL_PLATFORM_WINCE)
143 * Open/load the named driver and call its bootstrap function: _eglMain().
144 * By the time this function is called, the dpy->DriverName should have
147 * \return new _EGLDriver object.
150 _eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
155 char driverFilename[1000];
159 /* XXX also prepend a directory path??? */
160 sprintf(driverFilename, "%s.so", driverName);
162 _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
163 lib = dlopen(driverFilename, RTLD_NOW);
165 _eglLog(_EGL_WARNING, "Could not open %s (%s)",
166 driverFilename, dlerror());
170 mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
172 _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
177 drv = mainFunc(dpy, args);
182 /* with a recurvise open you want the inner most handle */
184 drv->LibHandle = lib;
193 _eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
195 void *handle = drv->LibHandle;
198 _eglLog(_EGL_INFO, "Closing driver");
201 * XXX check for currently bound context/surfaces and delete them?
204 b = drv->API.Terminate(drv, dpy);
211 * Given a display handle, return the _EGLDriver for that display.
214 _eglLookupDriver(EGLDisplay dpy)
216 _EGLDisplay *d = _eglLookupDisplay(dpy);
225 * Plug all the available fallback routines into the given driver's
229 _eglInitDriverFallbacks(_EGLDriver *drv)
231 /* If a pointer is set to NULL, then the device driver _really_ has
234 drv->API.Initialize = NULL;
235 drv->API.Terminate = NULL;
237 drv->API.GetConfigs = _eglGetConfigs;
238 drv->API.ChooseConfig = _eglChooseConfig;
239 drv->API.GetConfigAttrib = _eglGetConfigAttrib;
241 drv->API.CreateContext = _eglCreateContext;
242 drv->API.DestroyContext = _eglDestroyContext;
243 drv->API.MakeCurrent = _eglMakeCurrent;
244 drv->API.QueryContext = _eglQueryContext;
246 drv->API.CreateWindowSurface = _eglCreateWindowSurface;
247 drv->API.CreatePixmapSurface = _eglCreatePixmapSurface;
248 drv->API.CreatePbufferSurface = _eglCreatePbufferSurface;
249 drv->API.DestroySurface = _eglDestroySurface;
250 drv->API.QuerySurface = _eglQuerySurface;
251 drv->API.SurfaceAttrib = _eglSurfaceAttrib;
252 drv->API.BindTexImage = _eglBindTexImage;
253 drv->API.ReleaseTexImage = _eglReleaseTexImage;
254 drv->API.SwapInterval = _eglSwapInterval;
255 drv->API.SwapBuffers = _eglSwapBuffers;
256 drv->API.CopyBuffers = _eglCopyBuffers;
258 drv->API.QueryString = _eglQueryString;
259 drv->API.WaitGL = _eglWaitGL;
260 drv->API.WaitNative = _eglWaitNative;
262 #ifdef EGL_MESA_screen_surface
263 drv->API.ChooseModeMESA = _eglChooseModeMESA;
264 drv->API.GetModesMESA = _eglGetModesMESA;
265 drv->API.GetModeAttribMESA = _eglGetModeAttribMESA;
266 drv->API.GetScreensMESA = _eglGetScreensMESA;
267 drv->API.CreateScreenSurfaceMESA = _eglCreateScreenSurfaceMESA;
268 drv->API.ShowScreenSurfaceMESA = _eglShowScreenSurfaceMESA;
269 drv->API.ScreenPositionMESA = _eglScreenPositionMESA;
270 drv->API.QueryScreenMESA = _eglQueryScreenMESA;
271 drv->API.QueryScreenSurfaceMESA = _eglQueryScreenSurfaceMESA;
272 drv->API.QueryScreenModeMESA = _eglQueryScreenModeMESA;
273 drv->API.QueryModeStringMESA = _eglQueryModeStringMESA;
274 #endif /* EGL_MESA_screen_surface */
276 #ifdef EGL_VERSION_1_2
277 drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer;
278 #endif /* EGL_VERSION_1_2 */