egldisplay.c revision 545eaf83b5f096e5b16b2056e13b76f58d9211c9
1/** 2 * Functions related to EGLDisplay. 3 */ 4 5#include <assert.h> 6#include <stdlib.h> 7#include <string.h> 8#include "eglcontext.h" 9#include "eglsurface.h" 10#include "egldisplay.h" 11#include "egldriver.h" 12#include "eglglobals.h" 13#include "eglstring.h" 14#include "eglmutex.h" 15#include "egllog.h" 16 17 18/** 19 * Finish display management. 20 */ 21void 22_eglFiniDisplay(void) 23{ 24 _EGLDisplay *dpyList, *dpy; 25 26 /* atexit function is called with global mutex locked */ 27 dpyList = _eglGlobal.DisplayList; 28 while (dpyList) { 29 EGLint i; 30 31 /* pop list head */ 32 dpy = dpyList; 33 dpyList = dpyList->Next; 34 35 for (i = 0; i < _EGL_NUM_RESOURCES; i++) { 36 if (dpy->ResourceLists[i]) { 37 _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy); 38 break; 39 } 40 } 41 42 free(dpy); 43 } 44 _eglGlobal.DisplayList = NULL; 45} 46 47 48/** 49 * Allocate a new _EGLDisplay object for the given nativeDisplay handle. 50 * We'll also try to determine the device driver name at this time. 51 * 52 * Note that nativeDisplay may be an X Display ptr, or a string. 53 */ 54_EGLDisplay * 55_eglNewDisplay(EGLNativeDisplayType nativeDisplay) 56{ 57 _EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay)); 58 if (dpy) { 59 dpy->NativeDisplay = nativeDisplay; 60 } 61 return dpy; 62} 63 64 65/** 66 * Link a display to itself and return the handle of the link. 67 * The handle can be passed to client directly. 68 */ 69EGLDisplay 70_eglLinkDisplay(_EGLDisplay *dpy) 71{ 72 _eglLockMutex(_eglGlobal.Mutex); 73 74 dpy->Next = _eglGlobal.DisplayList; 75 _eglGlobal.DisplayList = dpy; 76 77 _eglUnlockMutex(_eglGlobal.Mutex); 78 79 return (EGLDisplay) dpy; 80} 81 82 83/** 84 * Unlink a linked display from itself. 85 * Accessing an unlinked display should generate EGL_BAD_DISPLAY error. 86 */ 87void 88_eglUnlinkDisplay(_EGLDisplay *dpy) 89{ 90 _EGLDisplay *prev; 91 92 _eglLockMutex(_eglGlobal.Mutex); 93 94 prev = _eglGlobal.DisplayList; 95 if (prev != dpy) { 96 while (prev) { 97 if (prev->Next == dpy) 98 break; 99 prev = prev->Next; 100 } 101 assert(prev); 102 prev->Next = dpy->Next; 103 } 104 else { 105 _eglGlobal.DisplayList = dpy->Next; 106 } 107 108 _eglUnlockMutex(_eglGlobal.Mutex); 109} 110 111 112/** 113 * Find the display corresponding to the specified native display id in all 114 * linked displays. 115 */ 116_EGLDisplay * 117_eglFindDisplay(EGLNativeDisplayType nativeDisplay) 118{ 119 _EGLDisplay *dpy; 120 121 _eglLockMutex(_eglGlobal.Mutex); 122 123 dpy = _eglGlobal.DisplayList; 124 while (dpy) { 125 if (dpy->NativeDisplay == nativeDisplay) { 126 _eglUnlockMutex(_eglGlobal.Mutex); 127 return dpy; 128 } 129 dpy = dpy->Next; 130 } 131 132 _eglUnlockMutex(_eglGlobal.Mutex); 133 134 return NULL; 135} 136 137 138/** 139 * Destroy the contexts and surfaces that are linked to the display. 140 */ 141void 142_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display) 143{ 144 _EGLResource *list; 145 146 list = display->ResourceLists[_EGL_RESOURCE_CONTEXT]; 147 while (list) { 148 _EGLContext *ctx = (_EGLContext *) list; 149 list = list->Next; 150 151 _eglUnlinkContext(ctx); 152 drv->API.DestroyContext(drv, display, ctx); 153 } 154 assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]); 155 156 list = display->ResourceLists[_EGL_RESOURCE_SURFACE]; 157 while (list) { 158 _EGLSurface *surf = (_EGLSurface *) list; 159 list = list->Next; 160 161 _eglUnlinkSurface(surf); 162 drv->API.DestroySurface(drv, display, surf); 163 } 164 assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]); 165} 166 167 168/** 169 * Free all the data hanging of an _EGLDisplay object, but not 170 * the object itself. 171 */ 172void 173_eglCleanupDisplay(_EGLDisplay *disp) 174{ 175 EGLint i; 176 177 if (disp->Configs) { 178 for (i = 0; i < disp->NumConfigs; i++) 179 free(disp->Configs[i]); 180 free(disp->Configs); 181 disp->Configs = NULL; 182 disp->NumConfigs = 0; 183 disp->MaxConfigs = 0; 184 } 185 186 /* XXX incomplete */ 187} 188 189 190#ifndef _EGL_SKIP_HANDLE_CHECK 191 192 193/** 194 * Return EGL_TRUE if the given handle is a valid handle to a display. 195 */ 196EGLBoolean 197_eglCheckDisplayHandle(EGLDisplay dpy) 198{ 199 _EGLDisplay *cur; 200 201 _eglLockMutex(_eglGlobal.Mutex); 202 cur = _eglGlobal.DisplayList; 203 while (cur) { 204 if (cur == (_EGLDisplay *) dpy) 205 break; 206 cur = cur->Next; 207 } 208 _eglUnlockMutex(_eglGlobal.Mutex); 209 return (cur != NULL); 210} 211 212 213/** 214 * Return EGL_TRUE if the given resource is valid. That is, the display does 215 * own the resource. 216 */ 217EGLBoolean 218_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy) 219{ 220 _EGLResource *list = dpy->ResourceLists[type]; 221 222 if (!res) 223 return EGL_FALSE; 224 225 while (list) { 226 if (res == (void *) list) { 227 assert(list->Display == dpy); 228 break; 229 } 230 list = list->Next; 231 } 232 233 return (list != NULL); 234} 235 236 237#endif /* !_EGL_SKIP_HANDLE_CHECK */ 238 239 240/** 241 * Link a resource to a display. 242 */ 243void 244_eglLinkResource(_EGLResource *res, _EGLResourceType type, _EGLDisplay *dpy) 245{ 246 assert(!res->Display || res->Display == dpy); 247 248 res->Display = dpy; 249 res->IsLinked = EGL_TRUE; 250 res->Next = dpy->ResourceLists[type]; 251 dpy->ResourceLists[type] = res; 252} 253 254 255/** 256 * Unlink a linked resource from its display. 257 */ 258void 259_eglUnlinkResource(_EGLResource *res, _EGLResourceType type) 260{ 261 _EGLResource *prev; 262 263 prev = res->Display->ResourceLists[type]; 264 if (prev != res) { 265 while (prev) { 266 if (prev->Next == res) 267 break; 268 prev = prev->Next; 269 } 270 assert(prev); 271 prev->Next = res->Next; 272 } 273 else { 274 res->Display->ResourceLists[type] = res->Next; 275 } 276 277 res->Next = NULL; 278 /* do not reset res->Display */ 279 res->IsLinked = EGL_FALSE; 280} 281