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"
19 #include "eglscreen.h"
20 #include "eglstring.h"
21 #include "eglsurface.h"
23 #if defined(_EGL_PLATFORM_X)
25 #elif defined(_EGL_PLATFORM_WINDOWS)
27 #elif defined(_EGL_PLATFORM_WINCE)
32 const char *DefaultDriverName
= ":0";
33 const char *SysFS
= "/sys/class";
39 * Given a card number, use sysfs to determine the DRI driver name.
42 _eglChooseDRMDriver(int card
)
45 return _eglstrdup("libEGLdri");
47 char path
[2000], driverName
[2000];
51 snprintf(path
, sizeof(path
), "%s/drm/card%d/dri_library_name", SysFS
, card
);
57 fgets(driverName
, sizeof(driverName
), f
);
60 if ((length
= strlen(driverName
)) > 1) {
61 /* remove the trailing newline from sysfs */
62 driverName
[length
- 1] = '\0';
63 strncat(driverName
, "_dri", sizeof(driverName
));
64 return _eglstrdup(driverName
);
74 * Determine/return the name of the driver to use for the given _EGLDisplay.
76 * Try to be clever and determine if nativeDisplay is an Xlib Display
77 * ptr or a string (naming a driver or screen number, etc).
79 * If the first character is ':' we interpret it as a screen or card index
80 * number (i.e. ":0" or ":1", etc)
81 * Else if the first character is '!' we interpret it as specific driver name
82 * (i.e. "!r200" or "!i830".
84 * Whatever follows ':' is copied and put into dpy->DriverArgs.
86 * The caller may free() the returned string.
89 _eglChooseDriver(_EGLDisplay
*dpy
)
91 const char *displayString
= (const char *) dpy
->NativeDisplay
;
92 const char *driverName
= NULL
;
95 /* choose a default */
96 displayString
= DefaultDriverName
;
99 /* extract default DriverArgs = whatever follows ':' */
100 if (displayString
[0] == '!' ||
101 displayString
[0] == ':') {
102 const char *args
= strchr(displayString
, ':');
104 dpy
->DriverArgs
= _eglstrdup(args
+ 1);
107 /* determine driver name now */
108 if (displayString
&& displayString
[0] == ':' &&
109 (displayString
[1] >= '0' && displayString
[1] <= '9') &&
111 int card
= atoi(displayString
+ 1);
112 driverName
= _eglChooseDRMDriver(card
);
114 else if (displayString
&& displayString
[0] == '!') {
115 /* use user-specified driver name */
116 driverName
= _eglstrdup(displayString
+ 1);
117 /* truncate driverName at ':' if present */
119 char *args
= strchr(driverName
, ':');
126 /* NativeDisplay is not a string! */
127 #if defined(_EGL_PLATFORM_X)
128 driverName
= _xeglChooseDriver(dpy
);
129 #elif defined(_EGL_PLATFORM_WINDOWS)
131 driverName
= _weglChooseDriver(dpy
);
132 #elif defined(_EGL_PLATFORM_WINCE)
142 * Open/load the named driver and call its bootstrap function: _eglMain().
143 * By the time this function is called, the dpy->DriverName should have
146 * \return new _EGLDriver object.
149 _eglOpenDriver(_EGLDisplay
*dpy
, const char *driverName
, const char *args
)
154 char driverFilename
[1000];
158 /* XXX also prepend a directory path??? */
159 sprintf(driverFilename
, "%s.so", driverName
);
161 _eglLog(_EGL_DEBUG
, "dlopen(%s)", driverFilename
);
162 lib
= dlopen(driverFilename
, RTLD_NOW
);
164 _eglLog(_EGL_WARNING
, "Could not open %s (%s)",
165 driverFilename
, dlerror());
169 mainFunc
= (_EGLMain_t
) dlsym(lib
, "_eglMain");
171 _eglLog(_EGL_WARNING
, "_eglMain not found in %s", driverFilename
);
176 drv
= mainFunc(dpy
, args
);
181 /* with a recurvise open you want the inner most handle */
183 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 */
283 * Examine the individual extension enable/disable flags and recompute
284 * the driver's Extensions string.
287 _eglUpdateExtensionsString(_EGLDriver
*drv
)
289 drv
->Extensions
.String
[0] = 0;
291 if (drv
->Extensions
.MESA_screen_surface
)
292 strcat(drv
->Extensions
.String
, "EGL_MESA_screen_surface ");
293 if (drv
->Extensions
.MESA_copy_context
)
294 strcat(drv
->Extensions
.String
, "EGL_MESA_copy_context ");
295 assert(strlen(drv
->Extensions
.String
) < _EGL_MAX_EXTENSIONS_LEN
);
301 _eglQueryString(_EGLDriver
*drv
, EGLDisplay dpy
, EGLint name
)
307 return _EGL_VENDOR_STRING
;
309 return _EGL_VERSION_STRING
;
311 _eglUpdateExtensionsString(drv
);
312 return drv
->Extensions
.String
;
313 #ifdef EGL_VERSION_1_2
314 case EGL_CLIENT_APIS
:
315 /* XXX need to initialize somewhere */
316 return drv
->ClientAPIs
;
319 _eglError(EGL_BAD_PARAMETER
, "eglQueryString");
326 _eglWaitGL(_EGLDriver
*drv
, EGLDisplay dpy
)
328 /* just a placeholder */
336 _eglWaitNative(_EGLDriver
*drv
, EGLDisplay dpy
, EGLint engine
)
338 /* just a placeholder */
342 case EGL_CORE_NATIVE_ENGINE
:
345 _eglError(EGL_BAD_PARAMETER
, "eglWaitNative(engine)");