egldisplay.c revision cdc920a0
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 "eglmutex.h" 14#include "egllog.h" 15 16 17/** 18 * Finish display management. 19 */ 20void 21_eglFiniDisplay(void) 22{ 23 _EGLDisplay *dpyList, *dpy; 24 25 /* atexit function is called with global mutex locked */ 26 dpyList = _eglGlobal.DisplayList; 27 while (dpyList) { 28 EGLint i; 29 30 /* pop list head */ 31 dpy = dpyList; 32 dpyList = dpyList->Next; 33 34 for (i = 0; i < _EGL_NUM_RESOURCES; i++) { 35 if (dpy->ResourceLists[i]) { 36 _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy); 37 break; 38 } 39 } 40 41 free(dpy); 42 } 43 _eglGlobal.DisplayList = NULL; 44} 45 46 47/** 48 * Find the display corresponding to the specified native display, or create a 49 * new one. 50 */ 51_EGLDisplay * 52_eglFindDisplay(EGLNativeDisplayType nativeDisplay) 53{ 54 _EGLDisplay *dpy; 55 56 _eglLockMutex(_eglGlobal.Mutex); 57 58 /* search the display list first */ 59 dpy = _eglGlobal.DisplayList; 60 while (dpy) { 61 if (dpy->NativeDisplay == nativeDisplay) 62 break; 63 dpy = dpy->Next; 64 } 65 66 /* create a new display */ 67 if (!dpy) { 68 dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay)); 69 if (dpy) { 70 _eglInitMutex(&dpy->Mutex); 71 dpy->NativeDisplay = nativeDisplay; 72 73 /* add to the display list */ 74 dpy->Next = _eglGlobal.DisplayList; 75 _eglGlobal.DisplayList = dpy; 76 } 77 } 78 79 _eglUnlockMutex(_eglGlobal.Mutex); 80 81 return dpy; 82} 83 84 85/** 86 * Destroy the contexts and surfaces that are linked to the display. 87 */ 88void 89_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display) 90{ 91 _EGLResource *list; 92 93 list = display->ResourceLists[_EGL_RESOURCE_CONTEXT]; 94 while (list) { 95 _EGLContext *ctx = (_EGLContext *) list; 96 list = list->Next; 97 98 _eglUnlinkContext(ctx); 99 drv->API.DestroyContext(drv, display, ctx); 100 } 101 assert(!display->ResourceLists[_EGL_RESOURCE_CONTEXT]); 102 103 list = display->ResourceLists[_EGL_RESOURCE_SURFACE]; 104 while (list) { 105 _EGLSurface *surf = (_EGLSurface *) list; 106 list = list->Next; 107 108 _eglUnlinkSurface(surf); 109 drv->API.DestroySurface(drv, display, surf); 110 } 111 assert(!display->ResourceLists[_EGL_RESOURCE_SURFACE]); 112} 113 114 115/** 116 * Free all the data hanging of an _EGLDisplay object, but not 117 * the object itself. 118 */ 119void 120_eglCleanupDisplay(_EGLDisplay *disp) 121{ 122 EGLint i; 123 124 if (disp->Configs) { 125 for (i = 0; i < disp->NumConfigs; i++) 126 free(disp->Configs[i]); 127 free(disp->Configs); 128 disp->Configs = NULL; 129 disp->NumConfigs = 0; 130 disp->MaxConfigs = 0; 131 } 132 133 /* XXX incomplete */ 134} 135 136 137/** 138 * Return EGL_TRUE if the given handle is a valid handle to a display. 139 */ 140EGLBoolean 141_eglCheckDisplayHandle(EGLDisplay dpy) 142{ 143 _EGLDisplay *cur; 144 145 _eglLockMutex(_eglGlobal.Mutex); 146 cur = _eglGlobal.DisplayList; 147 while (cur) { 148 if (cur == (_EGLDisplay *) dpy) 149 break; 150 cur = cur->Next; 151 } 152 _eglUnlockMutex(_eglGlobal.Mutex); 153 return (cur != NULL); 154} 155 156 157/** 158 * Return EGL_TRUE if the given resource is valid. That is, the display does 159 * own the resource. 160 */ 161EGLBoolean 162_eglCheckResource(void *res, _EGLResourceType type, _EGLDisplay *dpy) 163{ 164 _EGLResource *list = dpy->ResourceLists[type]; 165 166 if (!res) 167 return EGL_FALSE; 168 169 while (list) { 170 if (res == (void *) list) { 171 assert(list->Display == dpy); 172 break; 173 } 174 list = list->Next; 175 } 176 177 return (list != NULL); 178} 179 180 181/** 182 * Link a resource to a display. 183 */ 184void 185_eglLinkResource(_EGLResource *res, _EGLResourceType type, _EGLDisplay *dpy) 186{ 187 assert(!res->Display || res->Display == dpy); 188 189 res->Display = dpy; 190 res->IsLinked = EGL_TRUE; 191 res->Next = dpy->ResourceLists[type]; 192 dpy->ResourceLists[type] = res; 193} 194 195 196/** 197 * Unlink a linked resource from its display. 198 */ 199void 200_eglUnlinkResource(_EGLResource *res, _EGLResourceType type) 201{ 202 _EGLResource *prev; 203 204 prev = res->Display->ResourceLists[type]; 205 if (prev != res) { 206 while (prev) { 207 if (prev->Next == res) 208 break; 209 prev = prev->Next; 210 } 211 assert(prev); 212 prev->Next = res->Next; 213 } 214 else { 215 res->Display->ResourceLists[type] = res->Next; 216 } 217 218 res->Next = NULL; 219 /* do not reset res->Display */ 220 res->IsLinked = EGL_FALSE; 221} 222