egl: Move surface functions in egldisplay.[ch] to eglsurface.[ch]
[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 "eglstring.h"
14 #include "eglmutex.h"
15 #include "egllog.h"
16
17
18 /**
19 * Finish display management.
20 */
21 void
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 /* pop list head */
30 dpy = dpyList;
31 dpyList = dpyList->Next;
32
33 if (dpy->ContextList || dpy->SurfaceList)
34 _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy);
35
36 free(dpy);
37 }
38 _eglGlobal.DisplayList = NULL;
39 }
40
41
42 /**
43 * Allocate a new _EGLDisplay object for the given nativeDisplay handle.
44 * We'll also try to determine the device driver name at this time.
45 *
46 * Note that nativeDisplay may be an X Display ptr, or a string.
47 */
48 _EGLDisplay *
49 _eglNewDisplay(NativeDisplayType nativeDisplay)
50 {
51 _EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
52 if (dpy) {
53 dpy->NativeDisplay = nativeDisplay;
54 }
55 return dpy;
56 }
57
58
59 /**
60 * Link a display to itself and return the handle of the link.
61 * The handle can be passed to client directly.
62 */
63 EGLDisplay
64 _eglLinkDisplay(_EGLDisplay *dpy)
65 {
66 _eglLockMutex(_eglGlobal.Mutex);
67
68 dpy->Next = _eglGlobal.DisplayList;
69 _eglGlobal.DisplayList = dpy;
70
71 _eglUnlockMutex(_eglGlobal.Mutex);
72
73 return (EGLDisplay) dpy;
74 }
75
76
77 /**
78 * Unlink a linked display from itself.
79 * Accessing an unlinked display should generate EGL_BAD_DISPLAY error.
80 */
81 void
82 _eglUnlinkDisplay(_EGLDisplay *dpy)
83 {
84 _EGLDisplay *prev;
85
86 _eglLockMutex(_eglGlobal.Mutex);
87
88 prev = _eglGlobal.DisplayList;
89 if (prev != dpy) {
90 while (prev) {
91 if (prev->Next == dpy)
92 break;
93 prev = prev->Next;
94 }
95 assert(prev);
96 prev->Next = dpy->Next;
97 }
98 else {
99 _eglGlobal.DisplayList = dpy->Next;
100 }
101
102 _eglUnlockMutex(_eglGlobal.Mutex);
103 }
104
105
106 /**
107 * Find the display corresponding to the specified native display id in all
108 * linked displays.
109 */
110 _EGLDisplay *
111 _eglFindDisplay(NativeDisplayType nativeDisplay)
112 {
113 _EGLDisplay *dpy;
114
115 _eglLockMutex(_eglGlobal.Mutex);
116
117 dpy = _eglGlobal.DisplayList;
118 while (dpy) {
119 if (dpy->NativeDisplay == nativeDisplay) {
120 _eglUnlockMutex(_eglGlobal.Mutex);
121 return dpy;
122 }
123 dpy = dpy->Next;
124 }
125
126 _eglUnlockMutex(_eglGlobal.Mutex);
127
128 return NULL;
129 }
130
131
132 /**
133 * Destroy the contexts and surfaces that are linked to the display.
134 */
135 void
136 _eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display)
137 {
138 _EGLContext *contexts;
139 _EGLSurface *surfaces;
140
141 contexts = display->ContextList;
142 surfaces = display->SurfaceList;
143
144 while (contexts) {
145 _EGLContext *ctx = contexts;
146 contexts = contexts->Next;
147
148 _eglUnlinkContext(ctx);
149 drv->API.DestroyContext(drv, display, ctx);
150 }
151 assert(!display->ContextList);
152
153 while (surfaces) {
154 _EGLSurface *surf = surfaces;
155 surfaces = surfaces->Next;
156
157 _eglUnlinkSurface(surf);
158 drv->API.DestroySurface(drv, display, surf);
159 }
160 assert(!display->SurfaceList);
161 }
162
163
164 /**
165 * Free all the data hanging of an _EGLDisplay object, but not
166 * the object itself.
167 */
168 void
169 _eglCleanupDisplay(_EGLDisplay *disp)
170 {
171 EGLint i;
172
173 if (disp->Configs) {
174 for (i = 0; i < disp->NumConfigs; i++)
175 free(disp->Configs[i]);
176 free(disp->Configs);
177 disp->Configs = NULL;
178 disp->NumConfigs = 0;
179 }
180
181 /* XXX incomplete */
182 }
183
184
185 #ifndef _EGL_SKIP_HANDLE_CHECK
186
187
188 /**
189 * Return EGL_TRUE if the given handle is a valid handle to a display.
190 */
191 EGLBoolean
192 _eglCheckDisplayHandle(EGLDisplay dpy)
193 {
194 _EGLDisplay *cur;
195
196 _eglLockMutex(_eglGlobal.Mutex);
197 cur = _eglGlobal.DisplayList;
198 while (cur) {
199 if (cur == (_EGLDisplay *) dpy)
200 break;
201 cur = cur->Next;
202 }
203 _eglUnlockMutex(_eglGlobal.Mutex);
204 return (cur != NULL);
205 }
206
207
208 #endif /* !_EGL_SKIP_HANDLE_CHECK */