3 #include "eglcurrent.h"
4 #include "eglcontext.h"
8 /* a fallback thread info to guarantee that every thread always has one */
9 static _EGLThreadInfo dummy_thread
;
13 static __thread
const _EGLThreadInfo
*_egl_TSD
;
14 __attribute__ ((tls_model("initial-exec")));
16 static INLINE EGLBoolean
_eglInitTSD(void) { return EGL_TRUE
; }
17 static INLINE
void _eglFiniTSD(void) { }
18 static INLINE
void _eglSetTSD(const _EGLThreadInfo
*t
) { _egl_TSD
= t
; }
20 static INLINE _EGLThreadInfo
*_eglGetTSD(void)
22 return (_EGLThreadInfo
*) _egl_TSD
;
28 static pthread_key_t _egl_TSD
;
30 static INLINE EGLBoolean
_eglInitTSD(void)
32 return (pthread_key_create(&_egl_TSD
, NULL
) == 0);
35 static INLINE
void _eglFiniTSD(void)
37 pthread_key_delete(_egl_TSD
);
40 static INLINE
void _eglSetTSD(const _EGLThreadInfo
*t
)
42 pthread_setspecific(_egl_TSD
, (const void *) t
);
45 static INLINE _EGLThreadInfo
*_eglGetTSD(void)
47 return (_EGLThreadInfo
*) pthread_getspecific(_egl_TSD
);
51 static const _EGLThreadInfo
*_egl_TSD
;
53 static INLINE EGLBoolean
_eglInitTSD(void) { return EGL_TRUE
; }
54 static INLINE
void _eglFiniTSD(void) { }
55 static INLINE
void _eglSetTSD(const _EGLThreadInfo
*t
) { _egl_TSD
= t
; }
57 static INLINE _EGLThreadInfo
*_eglGetTSD(void)
59 return (_EGLThreadInfo
*) _egl_TSD
;
61 #endif /* !PTHREADS */
65 _eglInitThreadInfo(_EGLThreadInfo
*t
)
67 memset(t
, 0, sizeof(*t
));
68 t
->LastError
= EGL_SUCCESS
;
69 /* default, per EGL spec */
70 t
->CurrentAPIIndex
= _eglConvertApiToIndex(EGL_OPENGL_ES_API
);
75 * Allocate and init a new _EGLThreadInfo object.
77 static _EGLThreadInfo
*
78 _eglCreateThreadInfo(void)
80 _EGLThreadInfo
*t
= (_EGLThreadInfo
*) calloc(1, sizeof(_EGLThreadInfo
));
82 _eglInitThreadInfo(t
);
90 * Delete/free a _EGLThreadInfo object.
93 _eglDestroyThreadInfo(_EGLThreadInfo
*t
)
95 if (t
!= &dummy_thread
)
101 * Initialize "current thread" management.
104 _eglInitCurrent(void)
106 _eglInitThreadInfo(&dummy_thread
);
107 return _eglInitTSD();
112 * Finish "current thread" management.
115 _eglFiniCurrent(void)
117 /* TODO trace and release all threads... */
123 * Return the calling thread's thread info.
124 * If the calling thread nevers calls this function before, or if its thread
125 * info was destroyed, a new one is created. This function never returns NULL.
126 * In the case allocation fails, a dummy one is returned. See also
127 * _eglIsCurrentThreadDummy.
130 _eglGetCurrentThread(void)
132 _EGLThreadInfo
*t
= _eglGetTSD();
134 t
= _eglCreateThreadInfo();
143 * Destroy the calling thread's thread info.
146 _eglDestroyCurrentThread(void)
148 _EGLThreadInfo
*t
= _eglGetTSD();
150 _eglDestroyThreadInfo(t
);
157 * Return true if the calling thread's thread info is dummy.
158 * A dummy thread info is shared by all threads and should not be modified.
159 * Functions like eglBindAPI or eglMakeCurrent should check for dummy-ness
160 * before updating the thread info.
163 _eglIsCurrentThreadDummy(void)
165 _EGLThreadInfo
*t
= _eglGetTSD();
166 return (!t
|| t
== &dummy_thread
);
171 * Return the currently bound context, or NULL.
174 _eglGetCurrentContext(void)
176 _EGLThreadInfo
*t
= _eglGetCurrentThread();
177 return t
->CurrentContexts
[t
->CurrentAPIIndex
];
182 * Return the display of the currently bound context, or NULL.
185 _eglGetCurrentDisplay(void)
187 _EGLThreadInfo
*t
= _eglGetCurrentThread();
188 _EGLContext
*ctx
= t
->CurrentContexts
[t
->CurrentAPIIndex
];
197 * Return the read or write surface of the currently bound context, or NULL.
200 _eglGetCurrentSurface(EGLint readdraw
)
202 _EGLThreadInfo
*t
= _eglGetCurrentThread();
203 _EGLContext
*ctx
= t
->CurrentContexts
[t
->CurrentAPIIndex
];
207 return ctx
->DrawSurface
;
209 return ctx
->ReadSurface
;
219 * Record EGL error code.
222 _eglError(EGLint errCode
, const char *msg
)
224 _EGLThreadInfo
*t
= _eglGetCurrentThread();
227 if (t
== &dummy_thread
)
230 if (t
->LastError
== EGL_SUCCESS
) {
231 t
->LastError
= errCode
;
235 s
= "EGL_BAD_ACCESS";
240 case EGL_BAD_ATTRIBUTE
:
241 s
= "EGL_BAD_ATTRIBUTE";
244 s
= "EGL_BAD_CONFIG";
246 case EGL_BAD_CONTEXT
:
247 s
= "EGL_BAD_CONTEXT";
249 case EGL_BAD_CURRENT_SURFACE
:
250 s
= "EGL_BAD_CURRENT_SURFACE";
252 case EGL_BAD_DISPLAY
:
253 s
= "EGL_BAD_DISPLAY";
258 case EGL_BAD_NATIVE_PIXMAP
:
259 s
= "EGL_BAD_NATIVE_PIXMAP";
261 case EGL_BAD_NATIVE_WINDOW
:
262 s
= "EGL_BAD_NATIVE_WINDOW";
264 case EGL_BAD_PARAMETER
:
265 s
= "EGL_BAD_PARAMETER";
267 case EGL_BAD_SURFACE
:
268 s
= "EGL_BAD_SURFACE";
270 case EGL_BAD_SCREEN_MESA
:
271 s
= "EGL_BAD_SCREEN_MESA";
273 case EGL_BAD_MODE_MESA
:
274 s
= "EGL_BAD_MODE_MESA";
279 _eglLog(_EGL_DEBUG
, "EGL user error 0x%x (%s) in %s\n", errCode
, s
, msg
);