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