diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index decf1182067..008bc055b64 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -267,22 +267,17 @@ static EGLBoolean _eglSetFuncName(const char *funcName, _EGLDisplay *disp, EGLenum objectType, _EGLResource *object) { _EGLThreadInfo *thr = _eglGetCurrentThread(); - if (!_eglIsCurrentThreadDummy()) { - thr->CurrentFuncName = funcName; - thr->CurrentObjectLabel = NULL; + thr->CurrentFuncName = funcName; + thr->CurrentObjectLabel = NULL; - if (objectType == EGL_OBJECT_THREAD_KHR) - thr->CurrentObjectLabel = thr->Label; - else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp) - thr->CurrentObjectLabel = disp->Label; - else if (object) - thr->CurrentObjectLabel = object->Label; + if (objectType == EGL_OBJECT_THREAD_KHR) + thr->CurrentObjectLabel = thr->Label; + else if (objectType == EGL_OBJECT_DISPLAY_KHR && disp) + thr->CurrentObjectLabel = disp->Label; + else if (object) + thr->CurrentObjectLabel = object->Label; - return EGL_TRUE; - } - - _eglDebugReport(EGL_BAD_ALLOC, funcName, EGL_DEBUG_MSG_CRITICAL_KHR, NULL); - return EGL_FALSE; + return EGL_TRUE; } #define _EGL_FUNC_START(disp, objectType, object, ret) \ @@ -1645,8 +1640,7 @@ eglGetError(void) { _EGLThreadInfo *t = _eglGetCurrentThread(); EGLint e = t->LastError; - if (!_eglIsCurrentThreadDummy()) - t->LastError = EGL_SUCCESS; + t->LastError = EGL_SUCCESS; return e; } @@ -1674,8 +1668,6 @@ eglBindAPI(EGLenum api) _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE); t = _eglGetCurrentThread(); - if (_eglIsCurrentThreadDummy()) - RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); if (!_eglIsApiValid(api)) RETURN_EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); @@ -1723,19 +1715,17 @@ EGLBoolean EGLAPIENTRY eglReleaseThread(void) { /* unbind current contexts */ - if (!_eglIsCurrentThreadDummy()) { - _EGLThreadInfo *t = _eglGetCurrentThread(); - _EGLContext *ctx = t->CurrentContext; + _EGLThreadInfo *t = _eglGetCurrentThread(); + _EGLContext *ctx = t->CurrentContext; - _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE); + _EGL_FUNC_START(NULL, EGL_OBJECT_THREAD_KHR, NULL, EGL_FALSE); - if (ctx) { - _EGLDisplay *disp = ctx->Resource.Display; + if (ctx) { + _EGLDisplay *disp = ctx->Resource.Display; - mtx_lock(&disp->Mutex); - (void) disp->Driver->MakeCurrent(disp, NULL, NULL, NULL); - mtx_unlock(&disp->Mutex); - } + mtx_lock(&disp->Mutex); + (void) disp->Driver->MakeCurrent(disp, NULL, NULL, NULL); + mtx_unlock(&disp->Mutex); } _eglDestroyCurrentThread(); @@ -2434,12 +2424,8 @@ eglLabelObjectKHR(EGLDisplay dpy, EGLenum objectType, EGLObjectKHR object, if (objectType == EGL_OBJECT_THREAD_KHR) { _EGLThreadInfo *t = _eglGetCurrentThread(); - if (!_eglIsCurrentThreadDummy()) { - t->Label = label; - return EGL_SUCCESS; - } - - RETURN_EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_BAD_ALLOC); + t->Label = label; + return EGL_SUCCESS; } disp = _eglLockDisplay(dpy); diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c index 15de7c99496..aa483a6ff02 100644 --- a/src/egl/main/eglcontext.c +++ b/src/egl/main/eglcontext.c @@ -740,9 +740,6 @@ _eglCheckMakeCurrent(_EGLContext *ctx, _EGLSurface *draw, _EGLSurface *read) _EGLThreadInfo *t = _eglGetCurrentThread(); _EGLDisplay *disp; - if (_eglIsCurrentThreadDummy()) - return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent"); - /* this is easy */ if (!ctx) { if (draw || read) diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c index 6fdfd9469e1..75267e8a784 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -38,67 +38,9 @@ #include "eglcurrent.h" #include "eglglobals.h" -/* a fallback thread info to guarantee that every thread always has one */ -static _EGLThreadInfo dummy_thread; -static mtx_t _egl_TSDMutex = _MTX_INITIALIZER_NP; -static EGLBoolean _egl_TSDInitialized; -static tss_t _egl_TSD; -static void _eglDestroyThreadInfo(_EGLThreadInfo *t); - -#ifdef USE_ELF_TLS -static __THREAD_INITIAL_EXEC const _EGLThreadInfo *_egl_TLS; -#endif - -static inline void _eglSetTSD(const _EGLThreadInfo *t) -{ - tss_set(_egl_TSD, (void *) t); -#ifdef USE_ELF_TLS - _egl_TLS = t; -#endif -} - -static inline _EGLThreadInfo *_eglGetTSD(void) -{ -#ifdef USE_ELF_TLS - return (_EGLThreadInfo *) _egl_TLS; -#else - return (_EGLThreadInfo *) tss_get(_egl_TSD); -#endif -} - -static inline void _eglFiniTSD(void) -{ - mtx_lock(&_egl_TSDMutex); - if (_egl_TSDInitialized) { - _EGLThreadInfo *t = _eglGetTSD(); - - _egl_TSDInitialized = EGL_FALSE; - _eglDestroyThreadInfo(t); - tss_delete(_egl_TSD); - } - mtx_unlock(&_egl_TSDMutex); -} - -static inline EGLBoolean _eglInitTSD() -{ - if (!_egl_TSDInitialized) { - mtx_lock(&_egl_TSDMutex); - - /* check again after acquiring lock */ - if (!_egl_TSDInitialized) { - if (tss_create(&_egl_TSD, (void (*)(void *)) _eglDestroyThreadInfo) != thrd_success) { - mtx_unlock(&_egl_TSDMutex); - return EGL_FALSE; - } - _eglAddAtExitCall(_eglFiniTSD); - _egl_TSDInitialized = EGL_TRUE; - } - - mtx_unlock(&_egl_TSDMutex); - } - - return EGL_TRUE; -} +static __THREAD_INITIAL_EXEC _EGLThreadInfo _egl_TLS = { + .inited = false +}; static void _eglInitThreadInfo(_EGLThreadInfo *t) @@ -109,70 +51,21 @@ _eglInitThreadInfo(_EGLThreadInfo *t) } -/** - * Allocate and init a new _EGLThreadInfo object. - */ -static _EGLThreadInfo * -_eglCreateThreadInfo(void) -{ - _EGLThreadInfo *t = calloc(1, sizeof(_EGLThreadInfo)); - if (!t) - t = &dummy_thread; - - _eglInitThreadInfo(t); - return t; -} - - -/** - * Delete/free a _EGLThreadInfo object. - */ -static void -_eglDestroyThreadInfo(_EGLThreadInfo *t) -{ - if (t != &dummy_thread) { - free(t); -#ifdef USE_ELF_TLS - /* Reset the TLS also here, otherwise - * it will be having a dangling pointer */ - _egl_TLS = NULL; -#endif - } -} - - -/** - * Make sure TSD is initialized and return current value. - */ -static inline _EGLThreadInfo * -_eglCheckedGetTSD(void) -{ - if (_eglInitTSD() != EGL_TRUE) { - _eglLog(_EGL_FATAL, "failed to initialize \"current\" system"); - return NULL; - } - - return _eglGetTSD(); -} - - /** * Return the calling thread's thread info. * If the calling thread nevers calls this function before, or if its thread - * info was destroyed, a new one is created. This function never returns NULL. - * In the case allocation fails, a dummy one is returned. See also - * _eglIsCurrentThreadDummy. + * info was destroyed, reinitialize it. This function never returns NULL. */ _EGLThreadInfo * _eglGetCurrentThread(void) { - _EGLThreadInfo *t = _eglCheckedGetTSD(); - if (!t) { - t = _eglCreateThreadInfo(); - _eglSetTSD(t); + _EGLThreadInfo *current = &_egl_TLS; + if (unlikely(!current->inited)) { + memset(current, 0, sizeof(current[0])); + _eglInitThreadInfo(current); + current->inited = true; } - - return t; + return current; } @@ -182,25 +75,8 @@ _eglGetCurrentThread(void) void _eglDestroyCurrentThread(void) { - _EGLThreadInfo *t = _eglCheckedGetTSD(); - if (t) { - _eglDestroyThreadInfo(t); - _eglSetTSD(NULL); - } -} - - -/** - * Return true if the calling thread's thread info is dummy. - * A dummy thread info is shared by all threads and should not be modified. - * Functions like eglBindAPI or eglMakeCurrent should check for dummy-ness - * before updating the thread info. - */ -EGLBoolean -_eglIsCurrentThreadDummy(void) -{ - _EGLThreadInfo *t = _eglCheckedGetTSD(); - return (!t || t == &dummy_thread); + _EGLThreadInfo *t = _eglGetCurrentThread(); + t->inited = false; } @@ -223,9 +99,6 @@ _eglInternalError(EGLint errCode, const char *msg) { _EGLThreadInfo *t = _eglGetCurrentThread(); - if (t == &dummy_thread) - return EGL_FALSE; - t->LastError = errCode; if (errCode != EGL_SUCCESS) { diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h index 9bf76c806ae..d813a46d9ab 100644 --- a/src/egl/main/eglcurrent.h +++ b/src/egl/main/eglcurrent.h @@ -29,6 +29,8 @@ #ifndef EGLCURRENT_INCLUDED #define EGLCURRENT_INCLUDED +#include + #include "egltypedefs.h" @@ -49,6 +51,7 @@ extern "C" { */ struct _egl_thread_info { + bool inited; EGLint LastError; _EGLContext *CurrentContext; EGLenum CurrentAPI; @@ -86,10 +89,6 @@ extern void _eglDestroyCurrentThread(void); -extern EGLBoolean -_eglIsCurrentThreadDummy(void); - - extern _EGLContext * _eglGetCurrentContext(void);