diff options
-rw-r--r-- | src/egl/main/egldisplay.c | 85 | ||||
-rw-r--r-- | src/egl/main/egldisplay.h | 5 | ||||
-rw-r--r-- | src/egl/main/eglglobals.c | 6 | ||||
-rw-r--r-- | src/egl/main/eglglobals.h | 4 |
4 files changed, 78 insertions, 22 deletions
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index 5304b84a26..58d935225c 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -1,4 +1,3 @@ - /** * Functions related to EGLDisplay. */ @@ -13,6 +12,51 @@ #include "eglglobals.h" #include "eglhash.h" #include "eglstring.h" +#include "eglmutex.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 +_eglFiniDisplay(void) +{ + _eglLockMutex(&_eglDisplayInitMutex); + if (_eglDisplayHash) { + /* XXX TODO walk over table entries, deleting each */ + _eglDeleteHashTable(_eglDisplayHash); + _eglDisplayHash = NULL; + _eglDeleteHashTable(_eglSurfaceHash); + _eglSurfaceHash = NULL; + } + _eglUnlockMutex(&_eglDisplayInitMutex); +} + + +/* This can be avoided if hash table can be statically initialized */ +static INLINE void +_eglInitDisplay(void) +{ + if (!_eglDisplayHash) { + _eglLockMutex(&_eglDisplayInitMutex); + + /* check again after acquiring lock */ + if (!_eglDisplayHash) { + _eglDisplayHash = _eglNewHashTable(); + _eglSurfaceHash = _eglNewHashTable(); + + (void) _eglFiniDisplay; + } + + _eglUnlockMutex(&_eglDisplayInitMutex); + } +} /** @@ -31,6 +75,9 @@ _eglNewDisplay(NativeDisplayType nativeDisplay) dpy->Xdpy = (Display *) nativeDisplay; #endif + _eglInitDisplay(); + dpy->SurfaceHash = _eglSurfaceHash; + dpy->DriverName = _eglChooseDriver(dpy); if (!dpy->DriverName) { free(dpy); @@ -49,10 +96,13 @@ EGLDisplay _eglLinkDisplay(_EGLDisplay *dpy) { EGLuint key; - key = _eglHashGenKey(_eglGlobal.Displays); + + _eglInitDisplay(); + + key = _eglHashGenKey(_eglDisplayHash); assert(key); /* "link" the display to the hash table */ - _eglHashInsert(_eglGlobal.Displays, key, dpy); + _eglHashInsert(_eglDisplayHash, key, dpy); dpy->Handle = (EGLDisplay) _eglUIntToPointer(key); return dpy->Handle; @@ -67,7 +117,10 @@ void _eglUnlinkDisplay(_EGLDisplay *dpy) { EGLuint key = _eglPointerToUInt((void *) dpy->Handle); - _eglHashRemove(_eglGlobal.Displays, key); + + _eglInitDisplay(); + + _eglHashRemove(_eglDisplayHash, key); dpy->Handle = EGL_NO_DISPLAY; } @@ -84,7 +137,7 @@ _eglGetDisplayHandle(_EGLDisplay *display) return EGL_NO_DISPLAY; } - + /** * Lookup a handle to find the linked display. * Return NULL if the handle has no corresponding linked display. @@ -93,7 +146,10 @@ _EGLDisplay * _eglLookupDisplay(EGLDisplay dpy) { EGLuint key = _eglPointerToUInt((void *) dpy); - return (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key); + + _eglInitDisplay(); + + return (_EGLDisplay *) _eglHashLookup(_eglDisplayHash, key); } @@ -104,17 +160,20 @@ _eglLookupDisplay(EGLDisplay dpy) _EGLDisplay * _eglFindDisplay(NativeDisplayType nativeDisplay) { - EGLuint key = _eglHashFirstEntry(_eglGlobal.Displays); + EGLuint key; + + _eglInitDisplay(); /* Walk the hash table. Should switch to list if it is a problem. */ + key = _eglHashFirstEntry(_eglDisplayHash); while (key) { _EGLDisplay *dpy = (_EGLDisplay *) - _eglHashLookup(_eglGlobal.Displays, key); + _eglHashLookup(_eglDisplayHash, key); assert(dpy); if (dpy->NativeDisplay == nativeDisplay) return dpy; - key = _eglHashNextEntry(_eglGlobal.Displays, key); + key = _eglHashNextEntry(_eglDisplayHash, key); } return NULL; @@ -254,9 +313,9 @@ _eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy) surf->Next = dpy->SurfaceList; dpy->SurfaceList = surf; - key = _eglHashGenKey(_eglGlobal.Surfaces); + key = _eglHashGenKey(dpy->SurfaceHash); assert(key); - _eglHashInsert(_eglGlobal.Surfaces, key, surf); + _eglHashInsert(dpy->SurfaceHash, key, surf); surf->Handle = (EGLSurface) _eglUIntToPointer(key); return surf->Handle; @@ -273,7 +332,7 @@ _eglUnlinkSurface(_EGLSurface *surf) _EGLSurface *prev; EGLuint key = _eglPointerToUInt((void *) surf->Handle); - _eglHashRemove(_eglGlobal.Surfaces, key); + _eglHashRemove(surf->Display->SurfaceHash, key); surf->Handle = EGL_NO_SURFACE; prev = surf->Display->SurfaceList; @@ -317,5 +376,5 @@ _EGLSurface * _eglLookupSurface(EGLSurface surf) { EGLuint key = _eglPointerToUInt((void *) surf); - return (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces, key); + return (_EGLSurface *) _eglHashLookup(_eglSurfaceHash, key); } diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 2ef5db8a18..70c59ef5e4 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -6,6 +6,7 @@ #endif #include "egltypedefs.h" +#include "eglhash.h" struct _egl_display @@ -26,6 +27,10 @@ struct _egl_display /* lists of linked contexts and surface */ _EGLContext *ContextList; _EGLSurface *SurfaceList; + + /* hash table to map surfaces to handles */ + _EGLHashtable *SurfaceHash; + #ifdef _EGL_PLATFORM_X Display *Xdpy; #endif diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c index 23a3ef5ca8..f2c1c217a5 100644 --- a/src/egl/main/eglglobals.c +++ b/src/egl/main/eglglobals.c @@ -1,5 +1,6 @@ #include <stdlib.h> #include "eglglobals.h" +#include "egldisplay.h" #include "egllog.h" struct _egl_global _eglGlobal = @@ -15,8 +16,6 @@ void _eglInitGlobals(void) { if (!_eglGlobal.Initialized) { - _eglGlobal.Displays = _eglNewHashTable(); - _eglGlobal.Surfaces = _eglNewHashTable(); _eglGlobal.FreeScreenHandle = 1; _eglGlobal.Initialized = EGL_TRUE; @@ -31,7 +30,4 @@ _eglInitGlobals(void) void _eglDestroyGlobals(void) { - /* XXX TODO walk over table entries, deleting each */ - _eglDeleteHashTable(_eglGlobal.Displays); - _eglDeleteHashTable(_eglGlobal.Surfaces); } diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h index a9443cfbdd..47fd943fd5 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -13,10 +13,6 @@ struct _egl_global { EGLBoolean Initialized; - /* these are private to egldisplay.c */ - _EGLHashtable *Displays; - _EGLHashtable *Surfaces; - EGLScreenMESA FreeScreenHandle; /* bitmaks of supported APIs (supported by _some_ driver) */ |