diff options
Diffstat (limited to 'src/egl/main/egldriver.c')
-rw-r--r-- | src/egl/main/egldriver.c | 217 |
1 files changed, 112 insertions, 105 deletions
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index bda06dd827d..32842933ce2 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -1,82 +1,161 @@ +/** + * Functions for choosing and opening/loading device drivers. + */ + + #include <assert.h> +#include <string.h> #include <dlfcn.h> #include <stdio.h> -#include <string.h> +#include <stdlib.h> #include "eglconfig.h" #include "eglcontext.h" +#include "egldefines.h" #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" #include "egllog.h" +#include "eglmisc.h" #include "eglmode.h" #include "eglscreen.h" +#include "eglstring.h" #include "eglsurface.h" +#if defined(_EGL_PLATFORM_X) +#include "eglx.h" +#elif defined(_EGL_PLATFORM_WINDOWS) +/* XXX to do */ +#elif defined(_EGL_PLATFORM_WINCE) +/* XXX to do */ +#endif + + +const char *DefaultDriverName = ":0"; +const char *SysFS = "/sys/class"; + + + + +/** + * Given a card number, use sysfs to determine the DRI driver name. + */ +static const char * +_eglChooseDRMDriver(int card) +{ +#if 0 + return _eglstrdup("libEGLdri"); +#else + char path[2000], driverName[2000]; + FILE *f; + int length; + + snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", SysFS, card); -const char *DefaultDriverName = "demodriver"; + f = fopen(path, "r"); + if (!f) + return NULL; + + fgets(driverName, sizeof(driverName), f); + fclose(f); + + if ((length = strlen(driverName)) > 1) { + /* remove the trailing newline from sysfs */ + driverName[length - 1] = '\0'; + strncat(driverName, "_dri", sizeof(driverName)); + return _eglstrdup(driverName); + } + else { + return NULL; + } +#endif +} /** - * Choose and open/init the hardware driver for the given EGLDisplay. - * Previously, the EGLDisplay was created with _eglNewDisplay() where - * we recorded the user's NativeDisplayType parameter. + * Determine/return the name of the driver to use for the given _EGLDisplay. * - * Now we'll use the NativeDisplayType value. + * Try to be clever and determine if nativeDisplay is an Xlib Display + * ptr or a string (naming a driver or screen number, etc). * - * Currently, the native display value is treated as a string. * If the first character is ':' we interpret it as a screen or card index * number (i.e. ":0" or ":1", etc) * Else if the first character is '!' we interpret it as specific driver name * (i.e. "!r200" or "!i830". + * + * Whatever follows ':' is copied and put into dpy->DriverArgs. + * + * The caller may free() the returned string. */ -_EGLDriver * -_eglChooseDriver(EGLDisplay display) +const char * +_eglChooseDriver(_EGLDisplay *dpy) { - _EGLDisplay *dpy = _eglLookupDisplay(display); - _EGLDriver *drv; - const char *driverName = DefaultDriverName; - const char *name; + const char *displayString = (const char *) dpy->NativeDisplay; + const char *driverName = NULL; - assert(dpy); + if (!displayString) { + /* choose a default */ + displayString = DefaultDriverName; + } - name = dpy->Name; - if (!name) { - /* use default */ + /* extract default DriverArgs = whatever follows ':' */ + if (displayString[0] == '!' || + displayString[0] == ':') { + const char *args = strchr(displayString, ':'); + if (args) + dpy->DriverArgs = _eglstrdup(args + 1); } - else if (name[0] == ':' && (name[1] >= '0' && name[1] <= '9') && !name[2]) { - /* XXX probe hardware here to determine which driver to open */ - driverName = "libEGLdri"; + + /* determine driver name now */ + if (displayString && displayString[0] == ':' && + (displayString[1] >= '0' && displayString[1] <= '9') && + !displayString[2]) { + int card = atoi(displayString + 1); + driverName = _eglChooseDRMDriver(card); } - else if (name[0] == '!') { - /* use specified driver name */ - driverName = name + 1; + else if (displayString && displayString[0] == '!') { + /* use user-specified driver name */ + driverName = _eglstrdup(displayString + 1); + /* truncate driverName at ':' if present */ + { + char *args = strchr(driverName, ':'); + if (args) { + *args = 0; + } + } } else { - /* Maybe display was returned by XOpenDisplay? */ - _eglLog(_EGL_FATAL, "eglChooseDriver() bad name"); + /* NativeDisplay is not a string! */ +#if defined(_EGL_PLATFORM_X) + driverName = _xeglChooseDriver(dpy); +#elif defined(_EGL_PLATFORM_WINDOWS) + /* XXX to do */ + driverName = _weglChooseDriver(dpy); +#elif defined(_EGL_PLATFORM_WINCE) + /* XXX to do */ +#endif } - _eglLog(_EGL_INFO, "eglChooseDriver() choosing %s", driverName); - - drv = _eglOpenDriver(dpy, driverName); - dpy->Driver = drv; - - return drv; + return driverName; } /** * Open/load the named driver and call its bootstrap function: _eglMain(). + * By the time this function is called, the dpy->DriverName should have + * been determined. + * * \return new _EGLDriver object. */ _EGLDriver * -_eglOpenDriver(_EGLDisplay *dpy, const char *driverName) +_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args) { _EGLDriver *drv; _EGLMain_t mainFunc; void *lib; char driverFilename[1000]; + assert(driverName); + /* XXX also prepend a directory path??? */ sprintf(driverFilename, "%s.so", driverName); @@ -95,7 +174,7 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName) return NULL; } - drv = mainFunc(dpy); + drv = mainFunc(dpy, args); if (!drv) { dlclose(lib); return NULL; @@ -106,7 +185,6 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName) else dlclose(lib); - drv->Display = dpy; return drv; } @@ -199,74 +277,3 @@ _eglInitDriverFallbacks(_EGLDriver *drv) drv->API.CreatePbufferFromClientBuffer = _eglCreatePbufferFromClientBuffer; #endif /* EGL_VERSION_1_2 */ } - - -/** - * Examine the individual extension enable/disable flags and recompute - * the driver's Extensions string. - */ -static void -_eglUpdateExtensionsString(_EGLDriver *drv) -{ - drv->Extensions.String[0] = 0; - - if (drv->Extensions.MESA_screen_surface) - strcat(drv->Extensions.String, "EGL_MESA_screen_surface "); - if (drv->Extensions.MESA_copy_context) - strcat(drv->Extensions.String, "EGL_MESA_copy_context "); - assert(strlen(drv->Extensions.String) < MAX_EXTENSIONS_LEN); -} - - - -const char * -_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name) -{ - (void) drv; - (void) dpy; - switch (name) { - case EGL_VENDOR: - return "Mesa Project"; - case EGL_VERSION: - return "1.0"; - case EGL_EXTENSIONS: - _eglUpdateExtensionsString(drv); - return drv->Extensions.String; -#ifdef EGL_VERSION_1_2 - case EGL_CLIENT_APIS: - /* XXX need to initialize somewhere */ - return drv->ClientAPIs; -#endif - default: - _eglError(EGL_BAD_PARAMETER, "eglQueryString"); - return NULL; - } -} - - -EGLBoolean -_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy) -{ - /* just a placeholder */ - (void) drv; - (void) dpy; - return EGL_TRUE; -} - - -EGLBoolean -_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine) -{ - /* just a placeholder */ - (void) drv; - (void) dpy; - switch (engine) { - case EGL_CORE_NATIVE_ENGINE: - break; - default: - _eglError(EGL_BAD_PARAMETER, "eglWaitNative(engine)"); - return EGL_FALSE; - } - - return EGL_TRUE; -} |