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