diff options
Diffstat (limited to 'src/egl/main/egldisplay.c')
-rw-r--r-- | src/egl/main/egldisplay.c | 304 |
1 files changed, 141 insertions, 163 deletions
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index feae1d6040..2c271efd67 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -10,68 +10,62 @@ #include "egldisplay.h" #include "egldriver.h" #include "eglglobals.h" -#include "eglhash.h" #include "eglstring.h" #include "eglmutex.h" #include "egllog.h" -static _EGL_DECLARE_MUTEX(_eglDisplayInitMutex); -static _EGLHashtable *_eglDisplayHash; -/* TODO surface hash table should be per-display */ -static _EGLHashtable *_eglSurfaceHash; - - /** * Finish display management. */ -static void +void _eglFiniDisplay(void) { - _eglLockMutex(&_eglDisplayInitMutex); - if (_eglDisplayHash) { - EGLuint key = _eglHashFirstEntry(_eglDisplayHash); - - while (key) { - _EGLDisplay *dpy = (_EGLDisplay *) - _eglHashLookup(_eglDisplayHash, key); - assert(dpy); - - if (dpy->ContextList || dpy->SurfaceList) - _eglLog(_EGL_DEBUG, "Display %u is destroyed with resources", key); + _EGLDisplay *dpyList, *dpy; - _eglCleanupDisplay(dpy); - free(dpy); + /* atexit function is called with global mutex locked */ + dpyList = _eglGlobal.DisplayList; + while (dpyList) { + /* pop list head */ + dpy = dpyList; + dpyList = dpyList->Next; - key = _eglHashNextEntry(_eglDisplayHash, key); - } + if (dpy->ContextList || dpy->SurfaceList) + _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy); - _eglDeleteHashTable(_eglDisplayHash); - _eglDisplayHash = NULL; - _eglDeleteHashTable(_eglSurfaceHash); - _eglSurfaceHash = NULL; + free(dpy); } - _eglUnlockMutex(&_eglDisplayInitMutex); + _eglGlobal.DisplayList = NULL; } -/* This can be avoided if hash table can be statically initialized */ -static INLINE void -_eglInitDisplay(void) +/** + * If the first character is '!' we interpret it as specific driver name + * (i.e. "!r200" or "!i830"). Whatever follows ':' is interpreted as + * arguments. + * + * The caller may free() the returned driver name. + */ +char * +_eglSplitDisplayString(const char *dpyString, const char **args) { - if (!_eglDisplayHash) { - _eglLockMutex(&_eglDisplayInitMutex); - - /* check again after acquiring lock */ - if (!_eglDisplayHash) { - _eglDisplayHash = _eglNewHashTable(); - _eglSurfaceHash = _eglNewHashTable(); - - _eglAddAtExitCall(_eglFiniDisplay); - } - - _eglUnlockMutex(&_eglDisplayInitMutex); + char *drv, *p; + + if (!dpyString || dpyString[0] != '!') + return NULL; + drv = _eglstrdup(dpyString + 1); + if (!drv) + return NULL; + + p = strchr(dpyString, ':'); + if (p) { + drv[p - dpyString] = '\0'; + p++; } + if (args) + *args = p; + + return drv; } @@ -91,10 +85,7 @@ _eglNewDisplay(NativeDisplayType nativeDisplay) dpy->Xdpy = (Display *) nativeDisplay; #endif - _eglInitDisplay(); - dpy->SurfaceHash = _eglSurfaceHash; - - dpy->DriverName = _eglChooseDriver(dpy); + dpy->DriverName = _eglPreloadDriver(dpy); if (!dpy->DriverName) { free(dpy); return NULL; @@ -111,17 +102,14 @@ _eglNewDisplay(NativeDisplayType nativeDisplay) EGLDisplay _eglLinkDisplay(_EGLDisplay *dpy) { - EGLuint key; + _eglLockMutex(_eglGlobal.Mutex); - _eglInitDisplay(); + dpy->Next = _eglGlobal.DisplayList; + _eglGlobal.DisplayList = dpy; - key = _eglHashGenKey(_eglDisplayHash); - assert(key); - /* "link" the display to the hash table */ - _eglHashInsert(_eglDisplayHash, key, dpy); - dpy->Handle = (EGLDisplay) _eglUIntToPointer(key); + _eglUnlockMutex(_eglGlobal.Mutex); - return dpy->Handle; + return (EGLDisplay) dpy; } @@ -132,40 +120,25 @@ _eglLinkDisplay(_EGLDisplay *dpy) void _eglUnlinkDisplay(_EGLDisplay *dpy) { - EGLuint key = _eglPointerToUInt((void *) dpy->Handle); - - _eglInitDisplay(); - - _eglHashRemove(_eglDisplayHash, key); - dpy->Handle = EGL_NO_DISPLAY; -} - - -/** - * Return the handle of a linked display, or EGL_NO_DISPLAY. - */ -EGLDisplay -_eglGetDisplayHandle(_EGLDisplay *display) -{ - if (display) - return display->Handle; - else - return EGL_NO_DISPLAY; -} - + _EGLDisplay *prev; -/** - * Lookup a handle to find the linked display. - * Return NULL if the handle has no corresponding linked display. - */ -_EGLDisplay * -_eglLookupDisplay(EGLDisplay dpy) -{ - EGLuint key = _eglPointerToUInt((void *) dpy); + _eglLockMutex(_eglGlobal.Mutex); - _eglInitDisplay(); + prev = _eglGlobal.DisplayList; + if (prev != dpy) { + while (prev) { + if (prev->Next == dpy) + break; + prev = prev->Next; + } + assert(prev); + prev->Next = dpy->Next; + } + else { + _eglGlobal.DisplayList = dpy->Next; + } - return (_EGLDisplay *) _eglHashLookup(_eglDisplayHash, key); + _eglUnlockMutex(_eglGlobal.Mutex); } @@ -176,22 +149,21 @@ _eglLookupDisplay(EGLDisplay dpy) _EGLDisplay * _eglFindDisplay(NativeDisplayType nativeDisplay) { - EGLuint key; - - _eglInitDisplay(); + _EGLDisplay *dpy; - /* Walk the hash table. Should switch to list if it is a problem. */ - key = _eglHashFirstEntry(_eglDisplayHash); - while (key) { - _EGLDisplay *dpy = (_EGLDisplay *) - _eglHashLookup(_eglDisplayHash, key); - assert(dpy); + _eglLockMutex(_eglGlobal.Mutex); - if (dpy->NativeDisplay == nativeDisplay) + dpy = _eglGlobal.DisplayList; + while (dpy) { + if (dpy->NativeDisplay == nativeDisplay) { + _eglUnlockMutex(_eglGlobal.Mutex); return dpy; - key = _eglHashNextEntry(_eglDisplayHash, key); + } + dpy = dpy->Next; } + _eglUnlockMutex(_eglGlobal.Mutex); + return NULL; } @@ -200,29 +172,29 @@ _eglFindDisplay(NativeDisplayType nativeDisplay) * Destroy the contexts and surfaces that are linked to the display. */ void -_eglReleaseDisplayResources(_EGLDriver *drv, EGLDisplay dpy) +_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display) { - _EGLDisplay *display; _EGLContext *contexts; _EGLSurface *surfaces; - display = _eglLookupDisplay(dpy); - if (!display) - return; contexts = display->ContextList; surfaces = display->SurfaceList; while (contexts) { - EGLContext handle = _eglGetContextHandle(contexts); + _EGLContext *ctx = contexts; contexts = contexts->Next; - drv->API.DestroyContext(drv, dpy, handle); + + _eglUnlinkContext(ctx); + drv->API.DestroyContext(drv, display, ctx); } assert(!display->ContextList); while (surfaces) { - EGLSurface handle = _eglGetSurfaceHandle(surfaces); + _EGLSurface *surf = surfaces; surfaces = surfaces->Next; - drv->API.DestroySurface(drv, dpy, handle); + + _eglUnlinkSurface(surf); + drv->API.DestroySurface(drv, display, surf); } assert(!display->SurfaceList); } @@ -237,18 +209,15 @@ _eglCleanupDisplay(_EGLDisplay *disp) { EGLint i; - for (i = 0; i < disp->NumConfigs; i++) { - free(disp->Configs[i]); + if (disp->Configs) { + for (i = 0; i < disp->NumConfigs; i++) + free(disp->Configs[i]); + free(disp->Configs); + disp->Configs = NULL; + disp->NumConfigs = 0; } - free(disp->Configs); - disp->Configs = NULL; /* XXX incomplete */ - - free((void *) disp->DriverName); - disp->DriverName = NULL; - - /* driver deletes the _EGLDisplay object */ } @@ -295,46 +264,16 @@ _eglUnlinkContext(_EGLContext *ctx) /** - * Return the handle of a linked context, or EGL_NO_CONTEXT. - */ -EGLContext -_eglGetContextHandle(_EGLContext *ctx) -{ - return (EGLContext) ((ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT); -} - - -/** - * Lookup a handle to find the linked context. - * Return NULL if the handle has no corresponding linked context. - */ -_EGLContext * -_eglLookupContext(EGLContext ctx) -{ - _EGLContext *context = (_EGLContext *) ctx; - return (context && context->Display) ? context : NULL; -} - - -/** * Link a surface to a display and return the handle of the link. * The handle can be passed to client directly. */ EGLSurface _eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy) { - EGLuint key; - surf->Display = dpy; surf->Next = dpy->SurfaceList; dpy->SurfaceList = surf; - - key = _eglHashGenKey(dpy->SurfaceHash); - assert(key); - _eglHashInsert(dpy->SurfaceHash, key, surf); - - surf->Handle = (EGLSurface) _eglUIntToPointer(key); - return surf->Handle; + return (EGLSurface) surf; } @@ -346,10 +285,6 @@ void _eglUnlinkSurface(_EGLSurface *surf) { _EGLSurface *prev; - EGLuint key = _eglPointerToUInt((void *) surf->Handle); - - _eglHashRemove(surf->Display->SurfaceHash, key); - surf->Handle = EGL_NO_SURFACE; prev = surf->Display->SurfaceList; if (prev != surf) { @@ -371,26 +306,69 @@ _eglUnlinkSurface(_EGLSurface *surf) } +#ifndef _EGL_SKIP_HANDLE_CHECK + + /** - * Return the handle of a linked surface, or EGL_NO_SURFACE. + * Return EGL_TRUE if the given handle is a valid handle to a display. */ -EGLSurface -_eglGetSurfaceHandle(_EGLSurface *surface) +EGLBoolean +_eglCheckDisplayHandle(EGLDisplay dpy) { - if (surface) - return surface->Handle; - else - return EGL_NO_SURFACE; + _EGLDisplay *cur; + + _eglLockMutex(_eglGlobal.Mutex); + cur = _eglGlobal.DisplayList; + while (cur) { + if (cur == (_EGLDisplay *) dpy) + break; + cur = cur->Next; + } + _eglUnlockMutex(_eglGlobal.Mutex); + return (cur != NULL); } /** - * Lookup a handle to find the linked surface. - * Return NULL if the handle has no corresponding linked surface. + * Return EGL_TRUE if the given handle is a valid handle to a context. */ -_EGLSurface * -_eglLookupSurface(EGLSurface surf) +EGLBoolean +_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy) { - EGLuint key = _eglPointerToUInt((void *) surf); - return (_EGLSurface *) _eglHashLookup(_eglSurfaceHash, key); + _EGLContext *cur = NULL; + + if (dpy) + cur = dpy->ContextList; + while (cur) { + if (cur == (_EGLContext *) ctx) { + assert(cur->Display == dpy); + break; + } + cur = cur->Next; + } + return (cur != NULL); } + + +/** + * Return EGL_TRUE if the given handle is a valid handle to a surface. + */ +EGLBoolean +_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy) +{ + _EGLSurface *cur = NULL; + + if (dpy) + cur = dpy->SurfaceList; + while (cur) { + if (cur == (_EGLSurface *) surf) { + assert(cur->Display == dpy); + break; + } + cur = cur->Next; + } + return (cur != NULL); +} + + +#endif /* !_EGL_SKIP_HANDLE_CHECK */ |