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
= _eglPreloadDriver(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
*display
)
205 _EGLContext
*contexts
;
206 _EGLSurface
*surfaces
;
208 contexts
= display
->ContextList
;
209 surfaces
= display
->SurfaceList
;
212 _EGLContext
*ctx
= contexts
;
213 contexts
= contexts
->Next
;
215 _eglUnlinkContext(ctx
);
216 drv
->API
.DestroyContext(drv
, display
, ctx
);
218 assert(!display
->ContextList
);
221 _EGLSurface
*surf
= surfaces
;
222 surfaces
= surfaces
->Next
;
224 _eglUnlinkSurface(surf
);
225 drv
->API
.DestroySurface(drv
, display
, surf
);
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
;
251 * Link a context to a display and return the handle of the link.
252 * The handle can be passed to client directly.
255 _eglLinkContext(_EGLContext
*ctx
, _EGLDisplay
*dpy
)
258 ctx
->Next
= dpy
->ContextList
;
259 dpy
->ContextList
= ctx
;
260 return (EGLContext
) ctx
;
265 * Unlink a linked context from its display.
266 * Accessing an unlinked context should generate EGL_BAD_CONTEXT error.
269 _eglUnlinkContext(_EGLContext
*ctx
)
273 prev
= ctx
->Display
->ContextList
;
276 if (prev
->Next
== ctx
)
281 prev
->Next
= ctx
->Next
;
284 ctx
->Display
->ContextList
= ctx
->Next
;
293 * Return the handle of a linked context, or EGL_NO_CONTEXT.
296 _eglGetContextHandle(_EGLContext
*ctx
)
298 return (EGLContext
) ((ctx
&& ctx
->Display
) ? ctx
: EGL_NO_CONTEXT
);
303 * Lookup a handle to find the linked context.
304 * Return NULL if the handle has no corresponding linked context.
307 _eglLookupContext(EGLContext ctx
, _EGLDisplay
*dpy
)
309 _EGLContext
*context
= (_EGLContext
*) ctx
;
310 return (context
&& context
->Display
) ? context
: NULL
;
315 * Link a surface to a display and return the handle of the link.
316 * The handle can be passed to client directly.
319 _eglLinkSurface(_EGLSurface
*surf
, _EGLDisplay
*dpy
)
324 surf
->Next
= dpy
->SurfaceList
;
325 dpy
->SurfaceList
= surf
;
327 key
= _eglHashGenKey(dpy
->SurfaceHash
);
329 _eglHashInsert(dpy
->SurfaceHash
, key
, surf
);
331 surf
->Handle
= (EGLSurface
) _eglUIntToPointer(key
);
337 * Unlink a linked surface from its display.
338 * Accessing an unlinked surface should generate EGL_BAD_SURFACE error.
341 _eglUnlinkSurface(_EGLSurface
*surf
)
344 EGLuint key
= _eglPointerToUInt((void *) surf
->Handle
);
346 _eglHashRemove(surf
->Display
->SurfaceHash
, key
);
347 surf
->Handle
= EGL_NO_SURFACE
;
349 prev
= surf
->Display
->SurfaceList
;
352 if (prev
->Next
== surf
)
357 prev
->Next
= surf
->Next
;
361 surf
->Display
->SurfaceList
= surf
->Next
;
365 surf
->Display
= NULL
;
370 * Return the handle of a linked surface, or EGL_NO_SURFACE.
373 _eglGetSurfaceHandle(_EGLSurface
*surface
)
376 return surface
->Handle
;
378 return EGL_NO_SURFACE
;
383 * Lookup a handle to find the linked surface.
384 * Return NULL if the handle has no corresponding linked surface.
387 _eglLookupSurface(EGLSurface surf
, _EGLDisplay
*dpy
)
389 EGLuint key
= _eglPointerToUInt((void *) surf
);
390 return (_EGLSurface
*) _eglHashLookup(dpy
->SurfaceHash
, key
);