1 // 2 // Copyright(c) 2014 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // global_state.cpp : Implements functions for querying the thread-local GL and EGL state. 8 9 #include "libGLESv2/global_state.h" 10 11 #include "common/debug.h" 12 #include "common/platform.h" 13 #include "common/tls.h" 14 15 #include "libANGLE/Thread.h" 16 #include "libANGLE/Display.h" 17 18 namespace gl 19 { 20 GetGlobalContext()21Context *GetGlobalContext() 22 { 23 egl::Thread *thread = egl::GetCurrentThread(); 24 return thread->getContext(); 25 } 26 GetValidGlobalContext()27Context *GetValidGlobalContext() 28 { 29 egl::Thread *thread = egl::GetCurrentThread(); 30 return thread->getValidContext(); 31 } 32 33 } // namespace gl 34 35 namespace egl 36 { 37 38 namespace 39 { 40 41 static TLSIndex threadTLS = TLS_INVALID_INDEX; 42 AllocateCurrentThread()43Thread *AllocateCurrentThread() 44 { 45 ASSERT(threadTLS != TLS_INVALID_INDEX); 46 if (threadTLS == TLS_INVALID_INDEX) 47 { 48 return nullptr; 49 } 50 51 Thread *thread = new Thread(); 52 if (!SetTLSValue(threadTLS, thread)) 53 { 54 ERR() << "Could not set thread local storage."; 55 return nullptr; 56 } 57 58 return thread; 59 } 60 61 } // anonymous namespace 62 GetCurrentThread()63Thread *GetCurrentThread() 64 { 65 // Create a TLS index if one has not been created for this DLL 66 if (threadTLS == TLS_INVALID_INDEX) 67 { 68 threadTLS = CreateTLSIndex(); 69 } 70 71 Thread *current = static_cast<Thread *>(GetTLSValue(threadTLS)); 72 73 // ANGLE issue 488: when the dll is loaded after thread initialization, 74 // thread local storage (current) might not exist yet. 75 return (current ? current : AllocateCurrentThread()); 76 } 77 78 } // namespace egl 79 80 #ifdef ANGLE_PLATFORM_WINDOWS 81 namespace egl 82 { 83 84 namespace 85 { 86 DeallocateCurrentThread()87bool DeallocateCurrentThread() 88 { 89 Thread *thread = static_cast<Thread *>(GetTLSValue(threadTLS)); 90 SafeDelete(thread); 91 return SetTLSValue(threadTLS, nullptr); 92 } 93 InitializeProcess()94bool InitializeProcess() 95 { 96 threadTLS = CreateTLSIndex(); 97 if (threadTLS == TLS_INVALID_INDEX) 98 { 99 return false; 100 } 101 102 return AllocateCurrentThread() != nullptr; 103 } 104 TerminateProcess()105bool TerminateProcess() 106 { 107 if (!DeallocateCurrentThread()) 108 { 109 return false; 110 } 111 112 if (threadTLS != TLS_INVALID_INDEX) 113 { 114 TLSIndex tlsCopy = threadTLS; 115 threadTLS = TLS_INVALID_INDEX; 116 117 if (!DestroyTLSIndex(tlsCopy)) 118 { 119 return false; 120 } 121 } 122 123 return true; 124 } 125 126 } // anonymous namespace 127 128 } // namespace egl 129 DllMain(HINSTANCE,DWORD reason,LPVOID)130extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD reason, LPVOID) 131 { 132 switch (reason) 133 { 134 case DLL_PROCESS_ATTACH: 135 return static_cast<BOOL>(egl::InitializeProcess()); 136 137 case DLL_THREAD_ATTACH: 138 return static_cast<BOOL>(egl::AllocateCurrentThread() != nullptr); 139 140 case DLL_THREAD_DETACH: 141 return static_cast<BOOL>(egl::DeallocateCurrentThread()); 142 143 case DLL_PROCESS_DETACH: 144 egl::Display::CleanupDisplays(); 145 return static_cast<BOOL>(egl::TerminateProcess()); 146 } 147 148 return TRUE; 149 } 150 #endif // ANGLE_PLATFORM_WINDOWS 151