Merge branch 'glsl2-head' into glsl2
[mesa.git] / src / egl / main / egldisplay.c
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 */
20 void
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 */
88 void
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 */
119 void
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 */
140 EGLBoolean
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 */
161 EGLBoolean
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 */
184 void
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 */
199 void
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 }