summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libGLESv2/global_state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libGLESv2/global_state.cpp')
-rwxr-xr-xgfx/angle/src/libGLESv2/global_state.cpp148
1 files changed, 148 insertions, 0 deletions
diff --git a/gfx/angle/src/libGLESv2/global_state.cpp b/gfx/angle/src/libGLESv2/global_state.cpp
new file mode 100755
index 000000000..bc776b1f7
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/global_state.cpp
@@ -0,0 +1,148 @@
+//
+// Copyright(c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// global_state.cpp : Implements functions for querying the thread-local GL and EGL state.
+
+#include "libGLESv2/global_state.h"
+
+#include "common/debug.h"
+#include "common/platform.h"
+#include "common/tls.h"
+
+#include "libANGLE/Thread.h"
+
+namespace gl
+{
+
+Context *GetGlobalContext()
+{
+ egl::Thread *thread = egl::GetCurrentThread();
+ return thread->getContext();
+}
+
+Context *GetValidGlobalContext()
+{
+ egl::Thread *thread = egl::GetCurrentThread();
+ return thread->getValidContext();
+}
+
+} // namespace gl
+
+namespace egl
+{
+
+namespace
+{
+
+static TLSIndex threadTLS = TLS_INVALID_INDEX;
+
+Thread *AllocateCurrentThread()
+{
+ ASSERT(threadTLS != TLS_INVALID_INDEX);
+ if (threadTLS == TLS_INVALID_INDEX)
+ {
+ return nullptr;
+ }
+
+ Thread *thread = new Thread();
+ if (!SetTLSValue(threadTLS, thread))
+ {
+ ERR("Could not set thread local storage.");
+ return nullptr;
+ }
+
+ return thread;
+}
+
+} // anonymous namespace
+
+Thread *GetCurrentThread()
+{
+ // Create a TLS index if one has not been created for this DLL
+ if (threadTLS == TLS_INVALID_INDEX)
+ {
+ threadTLS = CreateTLSIndex();
+ }
+
+ 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
+
+#ifdef ANGLE_PLATFORM_WINDOWS
+namespace egl
+{
+
+namespace
+{
+
+bool DeallocateCurrentThread()
+{
+ Thread *thread = static_cast<Thread *>(GetTLSValue(threadTLS));
+ SafeDelete(thread);
+ return SetTLSValue(threadTLS, nullptr);
+}
+
+bool InitializeProcess()
+{
+ threadTLS = CreateTLSIndex();
+ if (threadTLS == TLS_INVALID_INDEX)
+ {
+ return false;
+ }
+
+ return AllocateCurrentThread() != nullptr;
+}
+
+bool TerminateProcess()
+{
+ if (!DeallocateCurrentThread())
+ {
+ return false;
+ }
+
+ if (threadTLS != TLS_INVALID_INDEX)
+ {
+ TLSIndex tlsCopy = threadTLS;
+ threadTLS = TLS_INVALID_INDEX;
+
+ if (!DestroyTLSIndex(tlsCopy))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // anonymous namespace
+
+} // namespace egl
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID)
+{
+ switch (reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ return static_cast<BOOL>(egl::InitializeProcess());
+
+ case DLL_THREAD_ATTACH:
+ return static_cast<BOOL>(egl::AllocateCurrentThread() != nullptr);
+
+ case DLL_THREAD_DETACH:
+ return static_cast<BOOL>(egl::DeallocateCurrentThread());
+
+ case DLL_PROCESS_DETACH:
+ return static_cast<BOOL>(egl::TerminateProcess());
+ }
+
+ return TRUE;
+}
+#endif // ANGLE_PLATFORM_WINDOWS