2 * Functions related to EGLDisplay.
8 #include "eglcontext.h"
9 #include "eglsurface.h"
10 #include "egldisplay.h"
11 #include "egldriver.h"
12 #include "eglglobals.h"
14 #include "eglstring.h"
18 static _EGL_DECLARE_MUTEX(_eglDisplayInitMutex
);
19 static _EGLHashtable
*_eglDisplayHash
;
20 /* TODO surface hash table should be per-display */
21 static _EGLHashtable
*_eglSurfaceHash
;
25 * Finish display management.
30 _eglLockMutex(&_eglDisplayInitMutex
);
31 if (_eglDisplayHash
) {
32 /* XXX TODO walk over table entries, deleting each */
33 _eglDeleteHashTable(_eglDisplayHash
);
34 _eglDisplayHash
= NULL
;
35 _eglDeleteHashTable(_eglSurfaceHash
);
36 _eglSurfaceHash
= NULL
;
38 _eglUnlockMutex(&_eglDisplayInitMutex
);
42 /* This can be avoided if hash table can be statically initialized */
46 if (!_eglDisplayHash
) {
47 _eglLockMutex(&_eglDisplayInitMutex
);
49 /* check again after acquiring lock */
50 if (!_eglDisplayHash
) {
51 _eglDisplayHash
= _eglNewHashTable();
52 _eglSurfaceHash
= _eglNewHashTable();
54 (void) _eglFiniDisplay
;
57 _eglUnlockMutex(&_eglDisplayInitMutex
);
63 * Allocate a new _EGLDisplay object for the given nativeDisplay handle.
64 * We'll also try to determine the device driver name at this time.
66 * Note that nativeDisplay may be an X Display ptr, or a string.
69 _eglNewDisplay(NativeDisplayType nativeDisplay
)
71 _EGLDisplay
*dpy
= (_EGLDisplay
*) calloc(1, sizeof(_EGLDisplay
));
73 dpy
->NativeDisplay
= nativeDisplay
;
74 #if defined(_EGL_PLATFORM_X)
75 dpy
->Xdpy
= (Display
*) nativeDisplay
;
79 dpy
->SurfaceHash
= _eglSurfaceHash
;
81 dpy
->DriverName
= _eglChooseDriver(dpy
);
82 if (!dpy
->DriverName
) {
92 * Link a display to itself and return the handle of the link.
93 * The handle can be passed to client directly.
96 _eglLinkDisplay(_EGLDisplay
*dpy
)
102 key
= _eglHashGenKey(_eglDisplayHash
);
104 /* "link" the display to the hash table */
105 _eglHashInsert(_eglDisplayHash
, key
, dpy
);
106 dpy
->Handle
= (EGLDisplay
) _eglUIntToPointer(key
);
113 * Unlink a linked display from itself.
114 * Accessing an unlinked display should generate EGL_BAD_DISPLAY error.
117 _eglUnlinkDisplay(_EGLDisplay
*dpy
)
119 EGLuint key
= _eglPointerToUInt((void *) dpy
->Handle
);
123 _eglHashRemove(_eglDisplayHash
, key
);
124 dpy
->Handle
= EGL_NO_DISPLAY
;
129 * Return the handle of a linked display, or EGL_NO_DISPLAY.
132 _eglGetDisplayHandle(_EGLDisplay
*display
)
135 return display
->Handle
;
137 return EGL_NO_DISPLAY
;
142 * Lookup a handle to find the linked display.
143 * Return NULL if the handle has no corresponding linked display.
146 _eglLookupDisplay(EGLDisplay dpy
)
148 EGLuint key
= _eglPointerToUInt((void *) dpy
);
152 return (_EGLDisplay
*) _eglHashLookup(_eglDisplayHash
, key
);
157 * Find the display corresponding to the specified native display id in all
161 _eglFindDisplay(NativeDisplayType nativeDisplay
)
167 /* Walk the hash table. Should switch to list if it is a problem. */
168 key
= _eglHashFirstEntry(_eglDisplayHash
);
170 _EGLDisplay
*dpy
= (_EGLDisplay
*)
171 _eglHashLookup(_eglDisplayHash
, key
);
174 if (dpy
->NativeDisplay
== nativeDisplay
)
176 key
= _eglHashNextEntry(_eglDisplayHash
, key
);
184 * Destroy the contexts and surfaces that are linked to the display.
187 _eglReleaseDisplayResources(_EGLDriver
*drv
, EGLDisplay dpy
)
189 _EGLDisplay
*display
;
190 _EGLContext
*contexts
;
191 _EGLSurface
*surfaces
;
193 display
= _eglLookupDisplay(dpy
);
196 contexts
= display
->ContextList
;
197 surfaces
= display
->SurfaceList
;
200 EGLContext handle
= _eglGetContextHandle(contexts
);
201 contexts
= contexts
->Next
;
202 drv
->API
.DestroyContext(drv
, dpy
, handle
);
204 assert(!display
->ContextList
);
207 EGLSurface handle
= _eglGetSurfaceHandle(surfaces
);
208 surfaces
= surfaces
->Next
;
209 drv
->API
.DestroySurface(drv
, dpy
, handle
);
211 assert(!display
->SurfaceList
);
216 * Free all the data hanging of an _EGLDisplay object, but not
220 _eglCleanupDisplay(_EGLDisplay
*disp
)
224 for (i
= 0; i
< disp
->NumConfigs
; i
++) {
225 free(disp
->Configs
[i
]);
228 disp
->Configs
= NULL
;
232 free((void *) disp
->DriverName
);
233 disp
->DriverName
= NULL
;
235 /* driver deletes the _EGLDisplay object */
240 * Link a context to a display and return the handle of the link.
241 * The handle can be passed to client directly.
244 _eglLinkContext(_EGLContext
*ctx
, _EGLDisplay
*dpy
)
247 ctx
->Next
= dpy
->ContextList
;
248 dpy
->ContextList
= ctx
;
249 return (EGLContext
) ctx
;
254 * Unlink a linked context from its display.
255 * Accessing an unlinked context should generate EGL_BAD_CONTEXT error.
258 _eglUnlinkContext(_EGLContext
*ctx
)
262 prev
= ctx
->Display
->ContextList
;
265 if (prev
->Next
== ctx
)
270 prev
->Next
= ctx
->Next
;
273 ctx
->Display
->ContextList
= ctx
->Next
;
282 * Return the handle of a linked context, or EGL_NO_CONTEXT.
285 _eglGetContextHandle(_EGLContext
*ctx
)
287 return (EGLContext
) ((ctx
&& ctx
->Display
) ? ctx
: EGL_NO_CONTEXT
);
292 * Lookup a handle to find the linked context.
293 * Return NULL if the handle has no corresponding linked context.
296 _eglLookupContext(EGLContext ctx
)
298 _EGLContext
*context
= (_EGLContext
*) ctx
;
299 return (context
&& context
->Display
) ? context
: NULL
;
304 * Link a surface to a display and return the handle of the link.
305 * The handle can be passed to client directly.
308 _eglLinkSurface(_EGLSurface
*surf
, _EGLDisplay
*dpy
)
313 surf
->Next
= dpy
->SurfaceList
;
314 dpy
->SurfaceList
= surf
;
316 key
= _eglHashGenKey(dpy
->SurfaceHash
);
318 _eglHashInsert(dpy
->SurfaceHash
, key
, surf
);
320 surf
->Handle
= (EGLSurface
) _eglUIntToPointer(key
);
326 * Unlink a linked surface from its display.
327 * Accessing an unlinked surface should generate EGL_BAD_SURFACE error.
330 _eglUnlinkSurface(_EGLSurface
*surf
)
333 EGLuint key
= _eglPointerToUInt((void *) surf
->Handle
);
335 _eglHashRemove(surf
->Display
->SurfaceHash
, key
);
336 surf
->Handle
= EGL_NO_SURFACE
;
338 prev
= surf
->Display
->SurfaceList
;
341 if (prev
->Next
== surf
)
346 prev
->Next
= surf
->Next
;
350 surf
->Display
->SurfaceList
= surf
->Next
;
354 surf
->Display
= NULL
;
359 * Return the handle of a linked surface, or EGL_NO_SURFACE.
362 _eglGetSurfaceHandle(_EGLSurface
*surface
)
365 return surface
->Handle
;
367 return EGL_NO_SURFACE
;
372 * Lookup a handle to find the linked surface.
373 * Return NULL if the handle has no corresponding linked surface.
376 _eglLookupSurface(EGLSurface surf
)
378 EGLuint key
= _eglPointerToUInt((void *) surf
);
379 return (_EGLSurface
*) _eglHashLookup(_eglSurfaceHash
, key
);