2 * Functions for choosing and opening/loading device drivers.
11 #include "eglconfig.h"
12 #include "eglcontext.h"
13 #include "egldisplay.h"
14 #include "egldriver.h"
15 #include "eglglobals.h"
18 #include "eglscreen.h"
19 #include "eglstring.h"
20 #include "eglsurface.h"
22 #if defined(_EGL_PLATFORM_X)
24 #elif defined(_EGL_PLATFORM_WINDOWS)
26 #elif defined(_EGL_PLATFORM_WINCE)
30 const char *DefaultDriverName
= ":0";
31 const char *SysFS
= "/sys/class";
37 * Given a card number, use sysfs to determine the DRI driver name.
40 _eglChooseDRMDriver(int card
)
43 return _eglstrdup("libEGLdri");
45 char path
[2000], driverName
[2000];
49 snprintf(path
, sizeof(path
), "%s/drm/card%d/dri_library_name", SysFS
, card
);
55 fgets(driverName
, sizeof(driverName
), f
);
58 if ((length
= strlen(driverName
)) > 1) {
59 /* remove the trailing newline from sysfs */
60 driverName
[length
- 1] = '\0';
61 strncat(driverName
, "_dri", sizeof(driverName
));
62 return _eglstrdup(driverName
);
72 * Determine/return the name of the driver to use for the given _EGLDisplay.
74 * Try to be clever and determine if nativeDisplay is an Xlib Display
75 * ptr or a string (naming a driver or screen number, etc).
77 * If the first character is ':' we interpret it as a screen or card index
78 * number (i.e. ":0" or ":1", etc)
79 * Else if the first character is '!' we interpret it as specific driver name
80 * (i.e. "!r200" or "!i830".
82 * Whatever follows ':' is copied and put into dpy->DriverArgs.
84 * The caller may free() the returned string.
87 _eglChooseDriver(_EGLDisplay
*dpy
)
89 const char *displayString
= (const char *) dpy
->NativeDisplay
;
90 const char *driverName
= NULL
;
93 /* choose a default */
94 displayString
= DefaultDriverName
;
97 /* extract default DriverArgs = whatever follows ':' */
98 if (displayString
[0] == '!' ||
99 displayString
[0] == ':') {
100 const char *args
= strchr(displayString
, ':');
102 dpy
->DriverArgs
= _eglstrdup(args
+ 1);
105 /* determine driver name now */
106 if (displayString
&& displayString
[0] == ':' &&
107 (displayString
[1] >= '0' && displayString
[1] <= '9') &&
109 int card
= atoi(displayString
+ 1);
110 driverName
= _eglChooseDRMDriver(card
);
112 else if (displayString
&& displayString
[0] == '!') {
113 /* use user-specified driver name */
114 driverName
= _eglstrdup(displayString
+ 1);
115 /* truncate driverName at ':' if present */
117 char *args
= strchr(driverName
, ':');
124 /* NativeDisplay is not a string! */
125 #if defined(_EGL_PLATFORM_X)
126 driverName
= _xeglChooseDriver(dpy
);
127 #elif defined(_EGL_PLATFORM_WINDOWS)
129 driverName
= _weglChooseDriver(dpy
);
130 #elif defined(_EGL_PLATFORM_WINCE)
140 * Open/load the named driver and call its bootstrap function: _eglMain().
141 * By the time this function is called, the dpy->DriverName should have
144 * \return new _EGLDriver object.
147 _eglOpenDriver(_EGLDisplay
*dpy
, const char *driverName
, const char *args
)
152 char driverFilename
[1000];
156 /* XXX also prepend a directory path??? */
157 sprintf(driverFilename
, "%s.so", driverName
);
159 _eglLog(_EGL_DEBUG
, "dlopen(%s)", driverFilename
);
160 lib
= dlopen(driverFilename
, RTLD_NOW
);
162 _eglLog(_EGL_WARNING
, "Could not open %s (%s)",
163 driverFilename
, dlerror());
167 mainFunc
= (_EGLMain_t
) dlsym(lib
, "_eglMain");
169 _eglLog(_EGL_WARNING
, "_eglMain not found in %s", driverFilename
);
174 drv
= mainFunc(dpy
, args
);
179 /* with a recurvise open you want the inner most handle */
181 drv
->LibHandle
= lib
;
191 _eglCloseDriver(_EGLDriver
*drv
, EGLDisplay dpy
)
193 void *handle
= drv
->LibHandle
;
196 _eglLog(_EGL_INFO
, "Closing driver");
199 * XXX check for currently bound context/surfaces and delete them?
202 b
= drv
->API
.Terminate(drv
, dpy
);
209 * Given a display handle, return the _EGLDriver for that display.
212 _eglLookupDriver(EGLDisplay dpy
)
214 _EGLDisplay
*d
= _eglLookupDisplay(dpy
);
223 * Plug all the available fallback routines into the given driver's
227 _eglInitDriverFallbacks(_EGLDriver
*drv
)
229 /* If a pointer is set to NULL, then the device driver _really_ has
232 drv
->API
.Initialize
= NULL
;
233 drv
->API
.Terminate
= NULL
;
235 drv
->API
.GetConfigs
= _eglGetConfigs
;
236 drv
->API
.ChooseConfig
= _eglChooseConfig
;
237 drv
->API
.GetConfigAttrib
= _eglGetConfigAttrib
;
239 drv
->API
.CreateContext
= _eglCreateContext
;
240 drv
->API
.DestroyContext
= _eglDestroyContext
;
241 drv
->API
.MakeCurrent
= _eglMakeCurrent
;
242 drv
->API
.QueryContext
= _eglQueryContext
;
244 drv
->API
.CreateWindowSurface
= _eglCreateWindowSurface
;
245 drv
->API
.CreatePixmapSurface
= _eglCreatePixmapSurface
;
246 drv
->API
.CreatePbufferSurface
= _eglCreatePbufferSurface
;
247 drv
->API
.DestroySurface
= _eglDestroySurface
;
248 drv
->API
.QuerySurface
= _eglQuerySurface
;
249 drv
->API
.SurfaceAttrib
= _eglSurfaceAttrib
;
250 drv
->API
.BindTexImage
= _eglBindTexImage
;
251 drv
->API
.ReleaseTexImage
= _eglReleaseTexImage
;
252 drv
->API
.SwapInterval
= _eglSwapInterval
;
253 drv
->API
.SwapBuffers
= _eglSwapBuffers
;
254 drv
->API
.CopyBuffers
= _eglCopyBuffers
;
256 drv
->API
.QueryString
= _eglQueryString
;
257 drv
->API
.WaitGL
= _eglWaitGL
;
258 drv
->API
.WaitNative
= _eglWaitNative
;
260 #ifdef EGL_MESA_screen_surface
261 drv
->API
.ChooseModeMESA
= _eglChooseModeMESA
;
262 drv
->API
.GetModesMESA
= _eglGetModesMESA
;
263 drv
->API
.GetModeAttribMESA
= _eglGetModeAttribMESA
;
264 drv
->API
.GetScreensMESA
= _eglGetScreensMESA
;
265 drv
->API
.CreateScreenSurfaceMESA
= _eglCreateScreenSurfaceMESA
;
266 drv
->API
.ShowScreenSurfaceMESA
= _eglShowScreenSurfaceMESA
;
267 drv
->API
.ScreenPositionMESA
= _eglScreenPositionMESA
;
268 drv
->API
.QueryScreenMESA
= _eglQueryScreenMESA
;
269 drv
->API
.QueryScreenSurfaceMESA
= _eglQueryScreenSurfaceMESA
;
270 drv
->API
.QueryScreenModeMESA
= _eglQueryScreenModeMESA
;
271 drv
->API
.QueryModeStringMESA
= _eglQueryModeStringMESA
;
272 #endif /* EGL_MESA_screen_surface */
274 #ifdef EGL_VERSION_1_2
275 drv
->API
.CreatePbufferFromClientBuffer
= _eglCreatePbufferFromClientBuffer
;
276 #endif /* EGL_VERSION_1_2 */
281 * Examine the individual extension enable/disable flags and recompute
282 * the driver's Extensions string.
285 _eglUpdateExtensionsString(_EGLDriver
*drv
)
287 drv
->Extensions
.String
[0] = 0;
289 if (drv
->Extensions
.MESA_screen_surface
)
290 strcat(drv
->Extensions
.String
, "EGL_MESA_screen_surface ");
291 if (drv
->Extensions
.MESA_copy_context
)
292 strcat(drv
->Extensions
.String
, "EGL_MESA_copy_context ");
293 assert(strlen(drv
->Extensions
.String
) < MAX_EXTENSIONS_LEN
);
299 _eglQueryString(_EGLDriver
*drv
, EGLDisplay dpy
, EGLint name
)
305 return "Mesa Project";
309 _eglUpdateExtensionsString(drv
);
310 return drv
->Extensions
.String
;
311 #ifdef EGL_VERSION_1_2
312 case EGL_CLIENT_APIS
:
313 /* XXX need to initialize somewhere */
314 return drv
->ClientAPIs
;
317 _eglError(EGL_BAD_PARAMETER
, "eglQueryString");
324 _eglWaitGL(_EGLDriver
*drv
, EGLDisplay dpy
)
326 /* just a placeholder */
334 _eglWaitNative(_EGLDriver
*drv
, EGLDisplay dpy
, EGLint engine
)
336 /* just a placeholder */
340 case EGL_CORE_NATIVE_ENGINE
:
343 _eglError(EGL_BAD_PARAMETER
, "eglWaitNative(engine)");