diff options
Diffstat (limited to 'src/egl/drivers/dri/egldri.c')
-rw-r--r-- | src/egl/drivers/dri/egldri.c | 143 |
1 files changed, 105 insertions, 38 deletions
diff --git a/src/egl/drivers/dri/egldri.c b/src/egl/drivers/dri/egldri.c index cab0be2bd1..9e400be624 100644 --- a/src/egl/drivers/dri/egldri.c +++ b/src/egl/drivers/dri/egldri.c @@ -1,5 +1,6 @@ /** - * Generic EGL driver for DRI. + * Generic EGL driver for DRI. This is basically an "adaptor" driver + * that allows libEGL to load/use regular DRI drivers. * * This file contains all the code needed to interface DRI-based drivers * with libEGL. @@ -23,6 +24,7 @@ #include "egldisplay.h" #include "eglcontext.h" #include "eglconfig.h" +#include "eglconfigutil.h" #include "eglsurface.h" #include "eglscreen.h" #include "eglglobals.h" @@ -32,18 +34,72 @@ #include "egldri.h" const char *sysfs = "/sys/class"; -#define None 0 + static const int empty_attribute_list[1] = { None }; + +/** + * Given a card number, return the name of the DRI driver to use. + * This generally means reading the contents of + * /sys/class/drm/cardX/dri_library_name, where X is the card number + */ +static EGLBoolean +driver_name_from_card_number(int card, char *driverName, int maxDriverName) +{ + char path[2000]; + FILE *f; + int length; + + snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", sysfs, card); + + f = fopen(path, "r"); + if (!f) + return EGL_FALSE; + + fgets(driverName, maxDriverName, f); + fclose(f); + + if ((length = strlen(driverName)) > 1) { + /* remove the trailing newline from sysfs */ + driverName[length - 1] = '\0'; + strncat(driverName, "_dri", maxDriverName); + return EGL_TRUE; + } + else { + return EGL_FALSE; + } +} + + + /** * The bootstrap function. * Return a new driDriver object and plug in API functions. * This function, in turn, loads a specific DRI driver (ex: r200_dri.so). */ _EGLDriver * -_eglMain(_EGLDisplay *dpy) +_eglMain(_EGLDisplay *dpy, const char *args) { +#if 1 + const int card = args ? atoi(args) : 0; + _EGLDriver *driver = NULL; + char driverName[1000]; + + if (!driver_name_from_card_number(card, driverName, sizeof(driverName))) { + _eglLog(_EGL_WARNING, + "Unable to determine driver name for card %d\n", card); + return NULL; + } + + _eglLog(_EGL_DEBUG, "Driver name: %s\n", driverName); + + driver = _eglOpenDriver(dpy, driverName, args); + + return driver; + +#else + int length; char path[NAME_MAX]; struct dirent *dirent; @@ -58,14 +114,19 @@ _eglMain(_EGLDisplay *dpy) _eglLog(_EGL_WARNING, "%s DRM devices not found.", path); return EGL_FALSE; } + + /* loop over dir entries looking for cardX where "X" is in the + * dpy->DriverName ":X" string. + */ while ((dirent = readdir(dir))) { if (strncmp(&dirent->d_name[0], "card", 4) != 0) continue; - if (strcmp(&dirent->d_name[4], &dpy->Name[1]) != 0) + if (strcmp(&dirent->d_name[4], &driverName[1]) != 0) continue; - snprintf(path, sizeof(path), "%s/drm/card%s/dri_library_name", sysfs, &dpy->Name[1]); + snprintf(path, sizeof(path), "%s/drm/card%s/dri_library_name", + sysfs, &driverName[1]); _eglLog(_EGL_INFO, "Opening %s", path); #if 1 file = fopen(path, "r"); @@ -89,6 +150,7 @@ _eglMain(_EGLDisplay *dpy) closedir(dir); return driver; +#endif } @@ -109,7 +171,10 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, if (!c) return EGL_NO_CONTEXT; - if (!_eglInitContext(drv, dpy, &c->Base, config, attrib_list)) { + conf = _eglLookupConfig(drv, dpy, config); + assert(conf); + + if (!_eglInitContext(drv, &c->Base, conf, attrib_list)) { free(c); return EGL_NO_CONTEXT; } @@ -127,8 +192,6 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, else sharePriv = NULL; - conf = _eglLookupConfig(drv, dpy, config); - assert(conf); _eglConfigToContextModesRec(conf, &visMode); c->driContext.private = disp->driScreen.createNewContext(disp, &visMode, @@ -138,10 +201,10 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, return EGL_FALSE; } - /* generate handle and insert into hash table */ - _eglSaveContext(&c->Base); + /* link to display */ + _eglLinkContext(&c->Base, &disp->Base); - return c->Base.Handle; + return _eglGetContextHandle(&c->Base); } @@ -152,13 +215,15 @@ _eglDRIMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, driDisplay *disp = Lookup_driDisplay(dpy); driContext *ctx = Lookup_driContext(context); EGLBoolean b; + __DRIid drawBuf = (__DRIid) draw; + __DRIid readBuf = (__DRIid) read; b = _eglMakeCurrent(drv, dpy, draw, read, context); if (!b) return EGL_FALSE; if (ctx) { - ctx->driContext.bindContext(disp, 0, read, draw, &ctx->driContext); + ctx->driContext.bindContext(disp, 0, drawBuf, readBuf, &ctx->driContext); } else { /* what's this??? */ @@ -173,14 +238,18 @@ _eglDRICreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { driSurface *surf; + _EGLConfig *conf; + + conf = _eglLookupConfig(drv, dpy, config); + assert(conf); surf = (driSurface *) calloc(1, sizeof(*surf)); if (!surf) { return EGL_NO_SURFACE; } - if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_PBUFFER_BIT, - config, attrib_list)) { + if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT, + conf, attrib_list)) { free(surf); return EGL_NO_SURFACE; } @@ -190,7 +259,7 @@ _eglDRICreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, #if 0 GLcontext *ctx = NULL; /* this _should_ be OK */ #endif - GLvisual visMode; + __GLcontextModes visMode; _EGLConfig *conf = _eglLookupConfig(drv, dpy, config); assert(conf); /* bad config should be caught earlier */ _eglConfigToContextModesRec(conf, &visMode); @@ -211,7 +280,7 @@ _eglDRICreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, #endif } - _eglSaveSurface(&surf->Base); + _eglLinkSurface(&surf->Base, _eglLookupDisplay(dpy)); return surf->Base.Handle; } @@ -223,16 +292,12 @@ _eglDRIDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface) driDisplay *disp = Lookup_driDisplay(dpy); driSurface *fs = Lookup_driSurface(surface); - _eglRemoveSurface(&fs->Base); + _eglUnlinkSurface(&fs->Base); fs->drawable.destroyDrawable(disp, fs->drawable.private); - if (fs->Base.IsBound) { - fs->Base.DeletePending = EGL_TRUE; - } - else { + if (!_eglIsSurfaceBound(&fs->Base)) free(fs); - } return EGL_TRUE; } @@ -243,16 +308,12 @@ _eglDRIDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context) driDisplay *disp = Lookup_driDisplay(dpy); driContext *fc = Lookup_driContext(context); - _eglRemoveContext(&fc->Base); + _eglUnlinkContext(&fc->Base); fc->driContext.destroyContext(disp, 0, fc->driContext.private); - if (fc->Base.IsBound) { - fc->Base.DeletePending = EGL_TRUE; - } - else { + if (!_eglIsContextBound(&fc->Base)) free(fc); - } return EGL_TRUE; } @@ -267,7 +328,8 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, _EGLConfig *config = _eglLookupConfig(drv, dpy, cfg); driDisplay *disp = Lookup_driDisplay(dpy); driSurface *surface; - GLvisual visMode; + __GLcontextModes visMode; + __DRIid drawBuf; surface = (driSurface *) calloc(1, sizeof(*surface)); if (!surface) { @@ -275,13 +337,13 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, } /* init base class, do error checking, etc. */ - if (!_eglInitSurface(drv, dpy, &surface->Base, EGL_SCREEN_BIT_MESA, - cfg, attrib_list)) { + if (!_eglInitSurface(drv, &surface->Base, EGL_SCREEN_BIT_MESA, + config, attrib_list)) { free(surface); return EGL_NO_SURFACE; } - _eglSaveSurface(&surface->Base); + _eglLinkSurface(&surface->Base &disp->Base); /* @@ -292,11 +354,13 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, /* convert EGLConfig to GLvisual */ _eglConfigToContextModesRec(config, &visMode); + drawBuf = (__DRIid) _eglGetSurfaceHandle(&surface->Base); + /* Create a new DRI drawable */ - if (!disp->driScreen.createNewDrawable(disp, &visMode, surface->Base.Handle, + if (!disp->driScreen.createNewDrawable(disp, &visMode, drawBuf, &surface->drawable, GLX_WINDOW_BIT, empty_attribute_list)) { - _eglRemoveSurface(&surface->Base); + _eglUnlinkSurface(&surface->Base); free(surface); return EGL_NO_SURFACE; } @@ -715,7 +779,7 @@ __eglGetDrawableInfo(__DRInativeDisplay * ndpy, int screen, __DRIid drawable, { __DRIscreen *pDRIScreen; __DRIscreenPrivate *psp; - driSurface *surf = Lookup_driSurface(drawable); + driSurface *surf = Lookup_driSurface((EGLSurface) drawable); pDRIScreen = __eglFindDRIScreen(ndpy, screen); @@ -1019,8 +1083,10 @@ _eglDRICreateDisplay(driDisplay *dpy, __DRIframebuffer *framebuffer) api_ver, & interface_methods, NULL); - if (!dpy->driScreen.private) + if (!dpy->driScreen.private) { + _eglLog(_EGL_WARNING, "egldri.c: DRI create new screen failed"); return EGL_FALSE; + } DRM_UNLOCK( dpy->drmFD, dpy->pSAREA, dpy->serverContext ); @@ -1080,6 +1146,7 @@ _eglDRIInitialize(_EGLDriver *drv, EGLDisplay dpy, { _EGLDisplay *disp = _eglLookupDisplay(dpy); driDisplay *display; + const char *driverName = (const char *) disp->NativeDisplay; assert(disp); @@ -1088,13 +1155,13 @@ _eglDRIInitialize(_EGLDriver *drv, EGLDisplay dpy, */ display = calloc(1, sizeof(*display)); display->Base = *disp; - _eglHashInsert(_eglGlobal.Displays, disp->Handle, display); + _eglSaveDisplay(&display->Base); free(disp); *major = 1; *minor = 0; - sscanf(&disp->Name[1], "%d", &display->minor); + sscanf(driverName + 1, "%d", &display->minor); drv->Initialized = EGL_TRUE; return EGL_TRUE; |