summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/egl/main/egldisplay.c85
-rw-r--r--src/egl/main/egldisplay.h5
-rw-r--r--src/egl/main/eglglobals.c6
-rw-r--r--src/egl/main/eglglobals.h4
4 files changed, 78 insertions, 22 deletions
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index 5304b84a26e..58d935225c6 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 2ef5db8a184..70c59ef5e46 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 23a3ef5ca82..f2c1c217a5d 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 a9443cfbdd8..47fd943fd53 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) */