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)
26 #elif defined(_EGL_PLATFORM_WINDOWS)
28 #elif defined(_EGL_PLATFORM_WINCE)
33 static const char *DefaultDriverName
= ":0";
34 static 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 * XXX this function is totally subject change!!!
78 * Determine/return the name of the driver to use for the given _EGLDisplay.
80 * Try to be clever and determine if nativeDisplay is an Xlib Display
81 * ptr or a string (naming a driver or screen number, etc).
83 * If the first character is ':' we interpret it as a screen or card index
84 * number (i.e. ":0" or ":1", etc)
85 * Else if the first character is '!' we interpret it as specific driver name
86 * (i.e. "!r200" or "!i830".
88 * Whatever follows ':' is copied and put into dpy->DriverArgs.
90 * The caller may free() the returned string.
93 _eglChooseDriver(_EGLDisplay
*dpy
)
95 const char *displayString
= (const char *) dpy
->NativeDisplay
;
96 const char *driverName
= NULL
;
98 (void) DefaultDriverName
;
100 /* First, if the EGL_DRIVER env var is set, use that */
101 driverName
= getenv("EGL_DRIVER");
103 return _eglstrdup(driverName
);
106 if (!displayString
) {
107 /* choose a default */
108 displayString
= DefaultDriverName
;
111 /* extract default DriverArgs = whatever follows ':' */
113 (displayString
[0] == '!' ||
114 displayString
[0] == ':')) {
115 const char *args
= strchr(displayString
, ':');
117 dpy
->DriverArgs
= _eglstrdup(args
+ 1);
120 /* determine driver name now */
121 if (displayString
&& displayString
[0] == ':' &&
122 (displayString
[1] >= '0' && displayString
[1] <= '9') &&
124 int card
= atoi(displayString
+ 1);
125 driverName
= _eglChooseDRMDriver(card
);
127 else if (displayString
&& displayString
[0] == '!') {
128 /* use user-specified driver name */
129 driverName
= _eglstrdup(displayString
+ 1);
130 /* truncate driverName at ':' if present */
132 char *args
= strchr(driverName
, ':');
139 /* NativeDisplay is not a string! */
140 #if defined(_EGL_PLATFORM_X)
141 driverName
= _xeglChooseDriver(dpy
);
142 #elif defined(_EGL_PLATFORM_WINDOWS)
144 driverName
= _weglChooseDriver(dpy
);
145 #elif defined(_EGL_PLATFORM_WINCE)
148 driverName
= DefaultDriverName
;
157 * Open/load the named driver and call its bootstrap function: _eglMain().
158 * By the time this function is called, the dpy->DriverName should have
161 * \return new _EGLDriver object.
164 _eglOpenDriver(_EGLDisplay
*dpy
, const char *driverName
, const char *args
)
168 #if defined(_EGL_PLATFORM_WINDOWS)
170 #elif defined(_EGL_PLATFORM_X)
173 char driverFilename
[1000];
177 #if defined(_EGL_PLATFORM_WINDOWS)
179 sprintf(driverFilename
, "%s.dll", driverName
);
180 _eglLog(_EGL_DEBUG
, "dlopen(%s)", driverFilename
);
181 lib
= LoadLibrary(driverFilename
);
182 #elif defined(_EGL_PLATFORM_X)
183 /* XXX also prepend a directory path??? */
184 sprintf(driverFilename
, "%s.so", driverName
);
185 _eglLog(_EGL_DEBUG
, "dlopen(%s)", driverFilename
);
186 lib
= dlopen(driverFilename
, RTLD_LAZY
);
190 _eglLog(_EGL_WARNING
, "Could not open %s (%s)",
191 driverFilename
, dlerror());
195 #if defined(_EGL_PLATFORM_WINDOWS)
196 mainFunc
= (_EGLMain_t
) GetProcAddress(lib
, "_eglMain");
197 #elif defined(_EGL_PLATFORM_X)
198 mainFunc
= (_EGLMain_t
) dlsym(lib
, "_eglMain");
202 _eglLog(_EGL_WARNING
, "_eglMain not found in %s", driverFilename
);
203 #if defined(_EGL_PLATFORM_WINDOWS)
205 #elif defined(_EGL_PLATFORM_X)
211 drv
= mainFunc(dpy
, args
);
213 #if defined(_EGL_PLATFORM_WINDOWS)
215 #elif defined(_EGL_PLATFORM_X)
221 /* with a recurvise open you want the inner most handle */
222 if (!drv
->LibHandle
) {
223 drv
->LibHandle
= lib
;
226 #if defined(_EGL_PLATFORM_WINDOWS)
228 #elif defined(_EGL_PLATFORM_X)
233 /* update the global notion of supported APIs */
234 _eglGlobal
.ClientAPIsMask
|= drv
->ClientAPIsMask
;
243 _eglCloseDriver(_EGLDriver
*drv
, EGLDisplay dpy
)
245 void *handle
= drv
->LibHandle
;
248 _eglLog(_EGL_DEBUG
, "Closing %s", drv
->Name
);
251 * XXX check for currently bound context/surfaces and delete them?
254 b
= drv
->API
.Terminate(drv
, dpy
);
256 #if defined(_EGL_PLATFORM_WINDOWS)
258 #elif defined(_EGL_PLATFORM_X)
267 * Save the given driver pointer in the list of all known drivers.
270 _eglSaveDriver(_EGLDriver
*drv
)
272 _eglGlobal
.Drivers
[ _eglGlobal
.NumDrivers
++ ] = drv
;
277 * Given a display handle, return the _EGLDriver for that display.
280 _eglLookupDriver(EGLDisplay dpy
)
282 _EGLDisplay
*d
= _eglLookupDisplay(dpy
);
291 * Plug all the available fallback routines into the given driver's
295 _eglInitDriverFallbacks(_EGLDriver
*drv
)
297 /* If a pointer is set to NULL, then the device driver _really_ has
300 drv
->API
.Initialize
= NULL
;
301 drv
->API
.Terminate
= NULL
;
303 drv
->API
.GetConfigs
= _eglGetConfigs
;
304 drv
->API
.ChooseConfig
= _eglChooseConfig
;
305 drv
->API
.GetConfigAttrib
= _eglGetConfigAttrib
;
307 drv
->API
.CreateContext
= _eglCreateContext
;
308 drv
->API
.DestroyContext
= _eglDestroyContext
;
309 drv
->API
.MakeCurrent
= _eglMakeCurrent
;
310 drv
->API
.QueryContext
= _eglQueryContext
;
312 drv
->API
.CreateWindowSurface
= _eglCreateWindowSurface
;
313 drv
->API
.CreatePixmapSurface
= _eglCreatePixmapSurface
;
314 drv
->API
.CreatePbufferSurface
= _eglCreatePbufferSurface
;
315 drv
->API
.DestroySurface
= _eglDestroySurface
;
316 drv
->API
.QuerySurface
= _eglQuerySurface
;
317 drv
->API
.SurfaceAttrib
= _eglSurfaceAttrib
;
318 drv
->API
.BindTexImage
= _eglBindTexImage
;
319 drv
->API
.ReleaseTexImage
= _eglReleaseTexImage
;
320 drv
->API
.SwapInterval
= _eglSwapInterval
;
321 drv
->API
.SwapBuffers
= _eglSwapBuffers
;
322 drv
->API
.CopyBuffers
= _eglCopyBuffers
;
324 drv
->API
.QueryString
= _eglQueryString
;
325 drv
->API
.WaitGL
= _eglWaitGL
;
326 drv
->API
.WaitNative
= _eglWaitNative
;
328 #ifdef EGL_MESA_screen_surface
329 drv
->API
.ChooseModeMESA
= _eglChooseModeMESA
;
330 drv
->API
.GetModesMESA
= _eglGetModesMESA
;
331 drv
->API
.GetModeAttribMESA
= _eglGetModeAttribMESA
;
332 drv
->API
.GetScreensMESA
= _eglGetScreensMESA
;
333 drv
->API
.CreateScreenSurfaceMESA
= _eglCreateScreenSurfaceMESA
;
334 drv
->API
.ShowScreenSurfaceMESA
= _eglShowScreenSurfaceMESA
;
335 drv
->API
.ScreenPositionMESA
= _eglScreenPositionMESA
;
336 drv
->API
.QueryScreenMESA
= _eglQueryScreenMESA
;
337 drv
->API
.QueryScreenSurfaceMESA
= _eglQueryScreenSurfaceMESA
;
338 drv
->API
.QueryScreenModeMESA
= _eglQueryScreenModeMESA
;
339 drv
->API
.QueryModeStringMESA
= _eglQueryModeStringMESA
;
340 #endif /* EGL_MESA_screen_surface */
342 #ifdef EGL_VERSION_1_2
343 drv
->API
.CreatePbufferFromClientBuffer
= _eglCreatePbufferFromClientBuffer
;
344 #endif /* EGL_VERSION_1_2 */