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
;
95 /* First, if the EGL_DRIVER env var is set, use that */
96 driverName
= getenv("EGL_DRIVER");
98 return _eglstrdup(driverName
);
101 if (!displayString
) {
102 /* choose a default */
103 displayString
= DefaultDriverName
;
106 /* extract default DriverArgs = whatever follows ':' */
108 (displayString
[0] == '!' ||
109 displayString
[0] == ':')) {
110 const char *args
= strchr(displayString
, ':');
112 dpy
->DriverArgs
= _eglstrdup(args
+ 1);
115 /* determine driver name now */
116 if (displayString
&& displayString
[0] == ':' &&
117 (displayString
[1] >= '0' && displayString
[1] <= '9') &&
119 int card
= atoi(displayString
+ 1);
120 driverName
= _eglChooseDRMDriver(card
);
122 else if (displayString
&& displayString
[0] == '!') {
123 /* use user-specified driver name */
124 driverName
= _eglstrdup(displayString
+ 1);
125 /* truncate driverName at ':' if present */
127 char *args
= strchr(driverName
, ':');
134 /* NativeDisplay is not a string! */
135 #if defined(_EGL_PLATFORM_X)
136 driverName
= _xeglChooseDriver(dpy
);
137 #elif defined(_EGL_PLATFORM_WINDOWS)
139 driverName
= _weglChooseDriver(dpy
);
140 #elif defined(_EGL_PLATFORM_WINCE)
150 * Open/load the named driver and call its bootstrap function: _eglMain().
151 * By the time this function is called, the dpy->DriverName should have
154 * \return new _EGLDriver object.
157 _eglOpenDriver(_EGLDisplay
*dpy
, const char *driverName
, const char *args
)
162 char driverFilename
[1000];
166 /* XXX also prepend a directory path??? */
167 sprintf(driverFilename
, "%s.so", driverName
);
169 _eglLog(_EGL_DEBUG
, "dlopen(%s)", driverFilename
);
170 lib
= dlopen(driverFilename
, RTLD_NOW
);
172 _eglLog(_EGL_WARNING
, "Could not open %s (%s)",
173 driverFilename
, dlerror());
177 mainFunc
= (_EGLMain_t
) dlsym(lib
, "_eglMain");
179 _eglLog(_EGL_WARNING
, "_eglMain not found in %s", driverFilename
);
184 drv
= mainFunc(dpy
, args
);
189 /* with a recurvise open you want the inner most handle */
191 drv
->LibHandle
= lib
;
195 /* update the global notion of supported APIs */
196 _eglGlobal
.ClientAPIsMask
|= drv
->ClientAPIsMask
;
203 _eglCloseDriver(_EGLDriver
*drv
, EGLDisplay dpy
)
205 void *handle
= drv
->LibHandle
;
208 _eglLog(_EGL_INFO
, "Closing driver");
211 * XXX check for currently bound context/surfaces and delete them?
214 b
= drv
->API
.Terminate(drv
, dpy
);
221 * Given a display handle, return the _EGLDriver for that display.
224 _eglLookupDriver(EGLDisplay dpy
)
226 _EGLDisplay
*d
= _eglLookupDisplay(dpy
);
235 * Plug all the available fallback routines into the given driver's
239 _eglInitDriverFallbacks(_EGLDriver
*drv
)
241 /* If a pointer is set to NULL, then the device driver _really_ has
244 drv
->API
.Initialize
= NULL
;
245 drv
->API
.Terminate
= NULL
;
247 drv
->API
.GetConfigs
= _eglGetConfigs
;
248 drv
->API
.ChooseConfig
= _eglChooseConfig
;
249 drv
->API
.GetConfigAttrib
= _eglGetConfigAttrib
;
251 drv
->API
.CreateContext
= _eglCreateContext
;
252 drv
->API
.DestroyContext
= _eglDestroyContext
;
253 drv
->API
.MakeCurrent
= _eglMakeCurrent
;
254 drv
->API
.QueryContext
= _eglQueryContext
;
256 drv
->API
.CreateWindowSurface
= _eglCreateWindowSurface
;
257 drv
->API
.CreatePixmapSurface
= _eglCreatePixmapSurface
;
258 drv
->API
.CreatePbufferSurface
= _eglCreatePbufferSurface
;
259 drv
->API
.DestroySurface
= _eglDestroySurface
;
260 drv
->API
.QuerySurface
= _eglQuerySurface
;
261 drv
->API
.SurfaceAttrib
= _eglSurfaceAttrib
;
262 drv
->API
.BindTexImage
= _eglBindTexImage
;
263 drv
->API
.ReleaseTexImage
= _eglReleaseTexImage
;
264 drv
->API
.SwapInterval
= _eglSwapInterval
;
265 drv
->API
.SwapBuffers
= _eglSwapBuffers
;
266 drv
->API
.CopyBuffers
= _eglCopyBuffers
;
268 drv
->API
.QueryString
= _eglQueryString
;
269 drv
->API
.WaitGL
= _eglWaitGL
;
270 drv
->API
.WaitNative
= _eglWaitNative
;
272 #ifdef EGL_MESA_screen_surface
273 drv
->API
.ChooseModeMESA
= _eglChooseModeMESA
;
274 drv
->API
.GetModesMESA
= _eglGetModesMESA
;
275 drv
->API
.GetModeAttribMESA
= _eglGetModeAttribMESA
;
276 drv
->API
.GetScreensMESA
= _eglGetScreensMESA
;
277 drv
->API
.CreateScreenSurfaceMESA
= _eglCreateScreenSurfaceMESA
;
278 drv
->API
.ShowScreenSurfaceMESA
= _eglShowScreenSurfaceMESA
;
279 drv
->API
.ScreenPositionMESA
= _eglScreenPositionMESA
;
280 drv
->API
.QueryScreenMESA
= _eglQueryScreenMESA
;
281 drv
->API
.QueryScreenSurfaceMESA
= _eglQueryScreenSurfaceMESA
;
282 drv
->API
.QueryScreenModeMESA
= _eglQueryScreenModeMESA
;
283 drv
->API
.QueryModeStringMESA
= _eglQueryModeStringMESA
;
284 #endif /* EGL_MESA_screen_surface */
286 #ifdef EGL_VERSION_1_2
287 drv
->API
.CreatePbufferFromClientBuffer
= _eglCreatePbufferFromClientBuffer
;
288 #endif /* EGL_VERSION_1_2 */