diff options
Diffstat (limited to 'gfx/angle/src/libGLESv2/global_state.cpp')
-rwxr-xr-x | gfx/angle/src/libGLESv2/global_state.cpp | 250 |
1 files changed, 169 insertions, 81 deletions
diff --git a/gfx/angle/src/libGLESv2/global_state.cpp b/gfx/angle/src/libGLESv2/global_state.cpp index bc776b1f7..fa681bde1 100755 --- a/gfx/angle/src/libGLESv2/global_state.cpp +++ b/gfx/angle/src/libGLESv2/global_state.cpp @@ -8,141 +8,229 @@ #include "libGLESv2/global_state.h" +#include "libANGLE/Context.h" +#include "libANGLE/Error.h" + #include "common/debug.h" #include "common/platform.h" #include "common/tls.h" -#include "libANGLE/Thread.h" - -namespace gl +namespace { -Context *GetGlobalContext() +static TLSIndex currentTLS = TLS_INVALID_INDEX; + +struct Current +{ + EGLint error; + EGLenum API; + egl::Display *display; + egl::Surface *drawSurface; + egl::Surface *readSurface; + gl::Context *context; +}; + +Current *AllocateCurrent() { - egl::Thread *thread = egl::GetCurrentThread(); - return thread->getContext(); + ASSERT(currentTLS != TLS_INVALID_INDEX); + if (currentTLS == TLS_INVALID_INDEX) + { + return NULL; + } + + Current *current = new Current(); + current->error = EGL_SUCCESS; + current->API = EGL_OPENGL_ES_API; + current->display = reinterpret_cast<egl::Display*>(EGL_NO_DISPLAY); + current->drawSurface = reinterpret_cast<egl::Surface*>(EGL_NO_SURFACE); + current->readSurface = reinterpret_cast<egl::Surface*>(EGL_NO_SURFACE); + current->context = reinterpret_cast<gl::Context*>(EGL_NO_CONTEXT); + + if (!SetTLSValue(currentTLS, current)) + { + ERR("Could not set thread local storage."); + return NULL; + } + + return current; } -Context *GetValidGlobalContext() +Current *GetCurrentData() { - egl::Thread *thread = egl::GetCurrentThread(); - return thread->getValidContext(); + // Create a TLS index if one has not been created for this DLL + if (currentTLS == TLS_INVALID_INDEX) + { + currentTLS = CreateTLSIndex(); + } + + Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS)); + + // ANGLE issue 488: when the dll is loaded after thread initialization, + // thread local storage (current) might not exist yet. + return (current ? current : AllocateCurrent()); } -} // namespace gl +#ifdef ANGLE_PLATFORM_WINDOWS -namespace egl +void DeallocateCurrent() { + Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS)); + SafeDelete(current); + SetTLSValue(currentTLS, NULL); +} -namespace +extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID) { + switch (reason) + { + case DLL_PROCESS_ATTACH: + currentTLS = CreateTLSIndex(); + if (currentTLS == TLS_INVALID_INDEX) + { + return FALSE; + } + AllocateCurrent(); + break; -static TLSIndex threadTLS = TLS_INVALID_INDEX; + case DLL_THREAD_ATTACH: + AllocateCurrent(); + break; -Thread *AllocateCurrentThread() -{ - ASSERT(threadTLS != TLS_INVALID_INDEX); - if (threadTLS == TLS_INVALID_INDEX) - { - return nullptr; - } + case DLL_THREAD_DETACH: + DeallocateCurrent(); + break; - Thread *thread = new Thread(); - if (!SetTLSValue(threadTLS, thread)) - { - ERR("Could not set thread local storage."); - return nullptr; + case DLL_PROCESS_DETACH: + DeallocateCurrent(); + if (currentTLS != TLS_INVALID_INDEX) + { + DestroyTLSIndex(currentTLS); + currentTLS = TLS_INVALID_INDEX; + } + break; } - return thread; + return TRUE; } +#endif -} // anonymous namespace +} -Thread *GetCurrentThread() +namespace gl { - // Create a TLS index if one has not been created for this DLL - if (threadTLS == TLS_INVALID_INDEX) + +Context *GetGlobalContext() +{ + Current *current = GetCurrentData(); + + return current->context; +} + +Context *GetValidGlobalContext() +{ + gl::Context *context = GetGlobalContext(); + if (context) { - threadTLS = CreateTLSIndex(); + if (context->isContextLost()) + { + context->handleError(gl::Error(GL_OUT_OF_MEMORY, "Context has been lost.")); + return nullptr; + } + else + { + return context; + } } + return nullptr; +} - Thread *current = static_cast<Thread *>(GetTLSValue(threadTLS)); +} - // ANGLE issue 488: when the dll is loaded after thread initialization, - // thread local storage (current) might not exist yet. - return (current ? current : AllocateCurrentThread()); +namespace egl +{ + +void SetGlobalError(const Error &error) +{ + Current *current = GetCurrentData(); + + current->error = error.getCode(); } -} // namespace egl +EGLint GetGlobalError() +{ + Current *current = GetCurrentData(); -#ifdef ANGLE_PLATFORM_WINDOWS -namespace egl + return current->error; +} + +EGLenum GetGlobalAPI() { + Current *current = GetCurrentData(); -namespace + return current->API; +} + +void SetGlobalAPI(EGLenum API) { + Current *current = GetCurrentData(); -bool DeallocateCurrentThread() + current->API = API; +} + +void SetGlobalDisplay(Display *dpy) { - Thread *thread = static_cast<Thread *>(GetTLSValue(threadTLS)); - SafeDelete(thread); - return SetTLSValue(threadTLS, nullptr); + Current *current = GetCurrentData(); + + current->display = dpy; } -bool InitializeProcess() +Display *GetGlobalDisplay() { - threadTLS = CreateTLSIndex(); - if (threadTLS == TLS_INVALID_INDEX) - { - return false; - } + Current *current = GetCurrentData(); - return AllocateCurrentThread() != nullptr; + return current->display; } -bool TerminateProcess() +void SetGlobalDrawSurface(Surface *surface) { - if (!DeallocateCurrentThread()) - { - return false; - } + Current *current = GetCurrentData(); - if (threadTLS != TLS_INVALID_INDEX) - { - TLSIndex tlsCopy = threadTLS; - threadTLS = TLS_INVALID_INDEX; + current->drawSurface = surface; +} - if (!DestroyTLSIndex(tlsCopy)) - { - return false; - } - } +Surface *GetGlobalDrawSurface() +{ + Current *current = GetCurrentData(); + + return current->drawSurface; +} - return true; +void SetGlobalReadSurface(Surface *surface) +{ + Current *current = GetCurrentData(); + + current->readSurface = surface; } -} // anonymous namespace +Surface *GetGlobalReadSurface() +{ + Current *current = GetCurrentData(); -} // namespace egl + return current->readSurface; +} -extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID) +void SetGlobalContext(gl::Context *context) { - switch (reason) - { - case DLL_PROCESS_ATTACH: - return static_cast<BOOL>(egl::InitializeProcess()); + Current *current = GetCurrentData(); - case DLL_THREAD_ATTACH: - return static_cast<BOOL>(egl::AllocateCurrentThread() != nullptr); + current->context = context; +} - case DLL_THREAD_DETACH: - return static_cast<BOOL>(egl::DeallocateCurrentThread()); +gl::Context *GetGlobalContext() +{ + Current *current = GetCurrentData(); - case DLL_PROCESS_DETACH: - return static_cast<BOOL>(egl::TerminateProcess()); - } + return current->context; +} - return TRUE; } -#endif // ANGLE_PLATFORM_WINDOWS |