1 // 2 // Copyright (c) 2002-2012 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 // main.cpp: DLL entry point and management of thread-local data. 8 9 #include "libEGL/main.h" 10 11 #include "common/debug.h" 12 #include "common/tls.h" 13 14 static TLSIndex currentTLS = TLS_OUT_OF_INDEXES; 15 16 namespace egl 17 { 18 19 Current *AllocateCurrent() 20 { 21 ASSERT(currentTLS != TLS_OUT_OF_INDEXES); 22 if (currentTLS == TLS_OUT_OF_INDEXES) 23 { 24 return NULL; 25 } 26 27 Current *current = new Current(); 28 current->error = EGL_SUCCESS; 29 current->API = EGL_OPENGL_ES_API; 30 current->display = EGL_NO_DISPLAY; 31 current->drawSurface = EGL_NO_SURFACE; 32 current->readSurface = EGL_NO_SURFACE; 33 34 if (!SetTLSValue(currentTLS, current)) 35 { 36 ERR("Could not set thread local storage."); 37 return NULL; 38 } 39 40 return current; 41 } 42 43 void DeallocateCurrent() 44 { 45 Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS)); 46 SafeDelete(current); 47 SetTLSValue(currentTLS, NULL); 48 } 49 50 } 51 52 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) 53 { 54 switch (reason) 55 { 56 case DLL_PROCESS_ATTACH: 57 { 58 #if defined(ANGLE_ENABLE_TRACE) 59 FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt"); 60 61 if (debug) 62 { 63 fclose(debug); 64 debug = fopen(TRACE_OUTPUT_FILE, "wt"); // Erase 65 66 if (debug) 67 { 68 fclose(debug); 69 } 70 } 71 #endif 72 73 currentTLS = CreateTLSIndex(); 74 if (currentTLS == TLS_OUT_OF_INDEXES) 75 { 76 return FALSE; 77 } 78 } 79 // Fall through to initialize index 80 case DLL_THREAD_ATTACH: 81 { 82 egl::AllocateCurrent(); 83 } 84 break; 85 case DLL_THREAD_DETACH: 86 { 87 egl::DeallocateCurrent(); 88 } 89 break; 90 case DLL_PROCESS_DETACH: 91 { 92 egl::DeallocateCurrent(); 93 DestroyTLSIndex(currentTLS); 94 } 95 break; 96 default: 97 break; 98 } 99 100 return TRUE; 101 } 102 103 namespace egl 104 { 105 106 Current *GetCurrentData() 107 { 108 Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS)); 109 110 // ANGLE issue 488: when the dll is loaded after thread initialization, 111 // thread local storage (current) might not exist yet. 112 return (current ? current : AllocateCurrent()); 113 } 114 115 void setCurrentError(EGLint error) 116 { 117 Current *current = GetCurrentData(); 118 119 current->error = error; 120 } 121 122 EGLint getCurrentError() 123 { 124 Current *current = GetCurrentData(); 125 126 return current->error; 127 } 128 129 void setCurrentAPI(EGLenum API) 130 { 131 Current *current = GetCurrentData(); 132 133 current->API = API; 134 } 135 136 EGLenum getCurrentAPI() 137 { 138 Current *current = GetCurrentData(); 139 140 return current->API; 141 } 142 143 void setCurrentDisplay(EGLDisplay dpy) 144 { 145 Current *current = GetCurrentData(); 146 147 current->display = dpy; 148 } 149 150 EGLDisplay getCurrentDisplay() 151 { 152 Current *current = GetCurrentData(); 153 154 return current->display; 155 } 156 157 void setCurrentDrawSurface(EGLSurface surface) 158 { 159 Current *current = GetCurrentData(); 160 161 current->drawSurface = surface; 162 } 163 164 EGLSurface getCurrentDrawSurface() 165 { 166 Current *current = GetCurrentData(); 167 168 return current->drawSurface; 169 } 170 171 void setCurrentReadSurface(EGLSurface surface) 172 { 173 Current *current = GetCurrentData(); 174 175 current->readSurface = surface; 176 } 177 178 EGLSurface getCurrentReadSurface() 179 { 180 Current *current = GetCurrentData(); 181 182 return current->readSurface; 183 } 184 185 void error(EGLint errorCode) 186 { 187 egl::setCurrentError(errorCode); 188 } 189 190 } 191