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) */ | 
