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"
19 static _EGL_DECLARE_MUTEX(_eglDisplayInitMutex
);
20 static _EGLHashtable
*_eglDisplayHash
;
21 /* TODO surface hash table should be per-display */
22 static _EGLHashtable
*_eglSurfaceHash
;
26 * Finish display management.
31 _eglLockMutex(&_eglDisplayInitMutex
);
32 if (_eglDisplayHash
) {
33 EGLuint key
= _eglHashFirstEntry(_eglDisplayHash
);
36 _EGLDisplay
*dpy
= (_EGLDisplay
*)
37 _eglHashLookup(_eglDisplayHash
, key
);
40 if (dpy
->ContextList
|| dpy
->SurfaceList
)
41 _eglLog(_EGL_DEBUG
, "Display %u is destroyed with resources", key
);
43 _eglCleanupDisplay(dpy
);
46 key
= _eglHashNextEntry(_eglDisplayHash
, key
);
49 _eglDeleteHashTable(_eglDisplayHash
);
50 _eglDisplayHash
= NULL
;
51 _eglDeleteHashTable(_eglSurfaceHash
);
52 _eglSurfaceHash
= NULL
;
54 _eglUnlockMutex(&_eglDisplayInitMutex
);
58 /* This can be avoided if hash table can be statically initialized */
62 if (!_eglDisplayHash
) {
63 _eglLockMutex(&_eglDisplayInitMutex
);
65 /* check again after acquiring lock */
66 if (!_eglDisplayHash
) {
67 _eglDisplayHash
= _eglNewHashTable();
68 _eglSurfaceHash
= _eglNewHashTable();
70 _eglAddAtExitCall(_eglFiniDisplay
);
73 _eglUnlockMutex(&_eglDisplayInitMutex
);
79 * Allocate a new _EGLDisplay object for the given nativeDisplay handle.
80 * We'll also try to determine the device driver name at this time.
82 * Note that nativeDisplay may be an X Display ptr, or a string.
85 _eglNewDisplay(NativeDisplayType nativeDisplay
)
87 _EGLDisplay
*dpy
= (_EGLDisplay
*) calloc(1, sizeof(_EGLDisplay
));
89 dpy
->NativeDisplay
= nativeDisplay
;
90 #if defined(_EGL_PLATFORM_X)
91 dpy
->Xdpy
= (Display
*) nativeDisplay
;
95 dpy
->SurfaceHash
= _eglSurfaceHash
;
97 dpy
->DriverName
= _eglChooseDriver(dpy
);
98 if (!dpy
->DriverName
) {
108 * Link a display to itself and return the handle of the link.
109 * The handle can be passed to client directly.
112 _eglLinkDisplay(_EGLDisplay
*dpy
)
118 key
= _eglHashGenKey(_eglDisplayHash
);
120 /* "link" the display to the hash table */
121 _eglHashInsert(_eglDisplayHash
, key
, dpy
);
122 dpy
->Handle
= (EGLDisplay
) _eglUIntToPointer(key
);
129 * Unlink a linked display from itself.
130 * Accessing an unlinked display should generate EGL_BAD_DISPLAY error.
133 _eglUnlinkDisplay(_EGLDisplay
*dpy
)
135 EGLuint key
= _eglPointerToUInt((void *) dpy
->Handle
);
139 _eglHashRemove(_eglDisplayHash
, key
);
140 dpy
->Handle
= EGL_NO_DISPLAY
;
145 * Return the handle of a linked display, or EGL_NO_DISPLAY.
148 _eglGetDisplayHandle(_EGLDisplay
*display
)
151 return display
->Handle
;
153 return EGL_NO_DISPLAY
;
158 * Lookup a handle to find the linked display.
159 * Return NULL if the handle has no corresponding linked display.
162 _eglLookupDisplay(EGLDisplay dpy
)
164 EGLuint key
= _eglPointerToUInt((void *) dpy
);
168 return (_EGLDisplay
*) _eglHashLookup(_eglDisplayHash
, key
);
173 * Find the display corresponding to the specified native display id in all
177 _eglFindDisplay(NativeDisplayType nativeDisplay
)
183 /* Walk the hash table. Should switch to list if it is a problem. */
184 key
= _eglHashFirstEntry(_eglDisplayHash
);
186 _EGLDisplay
*dpy
= (_EGLDisplay
*)
187 _eglHashLookup(_eglDisplayHash
, key
);
190 if (dpy
->NativeDisplay
== nativeDisplay
)
192 key
= _eglHashNextEntry(_eglDisplayHash
, key
);
200 * Destroy the contexts and surfaces that are linked to the display.
203 _eglReleaseDisplayResources(_EGLDriver
*drv
, EGLDisplay dpy
)
205 _EGLDisplay
*display
;
206 _EGLContext
*contexts
;
207 _EGLSurface
*surfaces
;
209 display
= _eglLookupDisplay(dpy
);
212 contexts
= display
->ContextList
;
213 surfaces
= display
->SurfaceList
;
216 EGLContext handle
= _eglGetContextHandle(contexts
);
217 contexts
= contexts
->Next
;
218 drv
->API
.DestroyContext(drv
, dpy
, handle
);
220 assert(!display
->ContextList
);
223 EGLSurface handle
= _eglGetSurfaceHandle(surfaces
);
224 surfaces
= surfaces
->Next
;
225 drv
->API
.DestroySurface(drv
, dpy
, handle
);
227 assert(!display
->SurfaceList
);
232 * Free all the data hanging of an _EGLDisplay object, but not
236 _eglCleanupDisplay(_EGLDisplay
*disp
)
240 for (i
= 0; i
< disp
->NumConfigs
; i
++) {
241 free(disp
->Configs
[i
]);
244 disp
->Configs
= NULL
;
248 free((void *) disp
->DriverName
);
249 disp
->DriverName
= NULL
;
251 /* driver deletes the _EGLDisplay object */
256 * Link a context to a display and return the handle of the link.
257 * The handle can be passed to client directly.
260 _eglLinkContext(_EGLContext
*ctx
, _EGLDisplay
*dpy
)
263 ctx
->Next
= dpy
->ContextList
;
264 dpy
->ContextList
= ctx
;
265 return (EGLContext
) ctx
;
270 * Unlink a linked context from its display.
271 * Accessing an unlinked context should generate EGL_BAD_CONTEXT error.
274 _eglUnlinkContext(_EGLContext
*ctx
)
278 prev
= ctx
->Display
->ContextList
;
281 if (prev
->Next
== ctx
)
286 prev
->Next
= ctx
->Next
;
289 ctx
->Display
->ContextList
= ctx
->Next
;
298 * Return the handle of a linked context, or EGL_NO_CONTEXT.
301 _eglGetContextHandle(_EGLContext
*ctx
)
303 return (EGLContext
) ((ctx
&& ctx
->Display
) ? ctx
: EGL_NO_CONTEXT
);
308 * Lookup a handle to find the linked context.
309 * Return NULL if the handle has no corresponding linked context.
312 _eglLookupContext(EGLContext ctx
)
314 _EGLContext
*context
= (_EGLContext
*) ctx
;
315 return (context
&& context
->Display
) ? context
: NULL
;
320 * Link a surface to a display and return the handle of the link.
321 * The handle can be passed to client directly.
324 _eglLinkSurface(_EGLSurface
*surf
, _EGLDisplay
*dpy
)
329 surf
->Next
= dpy
->SurfaceList
;
330 dpy
->SurfaceList
= surf
;
332 key
= _eglHashGenKey(dpy
->SurfaceHash
);
334 _eglHashInsert(dpy
->SurfaceHash
, key
, surf
);
336 surf
->Handle
= (EGLSurface
) _eglUIntToPointer(key
);
342 * Unlink a linked surface from its display.
343 * Accessing an unlinked surface should generate EGL_BAD_SURFACE error.
346 _eglUnlinkSurface(_EGLSurface
*surf
)
349 EGLuint key
= _eglPointerToUInt((void *) surf
->Handle
);
351 _eglHashRemove(surf
->Display
->SurfaceHash
, key
);
352 surf
->Handle
= EGL_NO_SURFACE
;
354 prev
= surf
->Display
->SurfaceList
;
357 if (prev
->Next
== surf
)
362 prev
->Next
= surf
->Next
;
366 surf
->Display
->SurfaceList
= surf
->Next
;
370 surf
->Display
= NULL
;
375 * Return the handle of a linked surface, or EGL_NO_SURFACE.
378 _eglGetSurfaceHandle(_EGLSurface
*surface
)
381 return surface
->Handle
;
383 return EGL_NO_SURFACE
;
388 * Lookup a handle to find the linked surface.
389 * Return NULL if the handle has no corresponding linked surface.
392 _eglLookupSurface(EGLSurface surf
)
394 EGLuint key
= _eglPointerToUInt((void *) surf
);
395 return (_EGLSurface
*) _eglHashLookup(_eglSurfaceHash
, key
);