• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
13 static DWORD currentTLS = TLS_OUT_OF_INDEXES;
14 
15 namespace egl
16 {
17 
AllocateCurrent()18 Current *AllocateCurrent()
19 {
20     Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
21 
22     if (!current)
23     {
24         ERR("Could not allocate thread local storage.");
25         return NULL;
26     }
27 
28     ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
29     TlsSetValue(currentTLS, current);
30 
31     current->error = EGL_SUCCESS;
32     current->API = EGL_OPENGL_ES_API;
33     current->display = EGL_NO_DISPLAY;
34     current->drawSurface = EGL_NO_SURFACE;
35     current->readSurface = EGL_NO_SURFACE;
36 
37     return current;
38 }
39 
DeallocateCurrent()40 void DeallocateCurrent()
41 {
42     void *current = TlsGetValue(currentTLS);
43 
44     if (current)
45     {
46         LocalFree((HLOCAL)current);
47     }
48 }
49 
50 }
51 
DllMain(HINSTANCE instance,DWORD reason,LPVOID reserved)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 = TlsAlloc();
74 
75             if (currentTLS == TLS_OUT_OF_INDEXES)
76             {
77                 return FALSE;
78             }
79         }
80         // Fall throught to initialize index
81       case DLL_THREAD_ATTACH:
82         {
83             egl::AllocateCurrent();
84         }
85         break;
86       case DLL_THREAD_DETACH:
87         {
88             egl::DeallocateCurrent();
89         }
90         break;
91       case DLL_PROCESS_DETACH:
92         {
93             egl::DeallocateCurrent();
94             TlsFree(currentTLS);
95         }
96         break;
97       default:
98         break;
99     }
100 
101     return TRUE;
102 }
103 
104 namespace egl
105 {
106 
GetCurrentData()107 Current *GetCurrentData()
108 {
109     Current *current = (Current*)TlsGetValue(currentTLS);
110 
111     // ANGLE issue 488: when the dll is loaded after thread initialization,
112     // thread local storage (current) might not exist yet.
113     return (current ? current : AllocateCurrent());
114 }
115 
setCurrentError(EGLint error)116 void setCurrentError(EGLint error)
117 {
118     Current *current = GetCurrentData();
119 
120     current->error = error;
121 }
122 
getCurrentError()123 EGLint getCurrentError()
124 {
125     Current *current = GetCurrentData();
126 
127     return current->error;
128 }
129 
setCurrentAPI(EGLenum API)130 void setCurrentAPI(EGLenum API)
131 {
132     Current *current = GetCurrentData();
133 
134     current->API = API;
135 }
136 
getCurrentAPI()137 EGLenum getCurrentAPI()
138 {
139     Current *current = GetCurrentData();
140 
141     return current->API;
142 }
143 
setCurrentDisplay(EGLDisplay dpy)144 void setCurrentDisplay(EGLDisplay dpy)
145 {
146     Current *current = GetCurrentData();
147 
148     current->display = dpy;
149 }
150 
getCurrentDisplay()151 EGLDisplay getCurrentDisplay()
152 {
153     Current *current = GetCurrentData();
154 
155     return current->display;
156 }
157 
setCurrentDrawSurface(EGLSurface surface)158 void setCurrentDrawSurface(EGLSurface surface)
159 {
160     Current *current = GetCurrentData();
161 
162     current->drawSurface = surface;
163 }
164 
getCurrentDrawSurface()165 EGLSurface getCurrentDrawSurface()
166 {
167     Current *current = GetCurrentData();
168 
169     return current->drawSurface;
170 }
171 
setCurrentReadSurface(EGLSurface surface)172 void setCurrentReadSurface(EGLSurface surface)
173 {
174     Current *current = GetCurrentData();
175 
176     current->readSurface = surface;
177 }
178 
getCurrentReadSurface()179 EGLSurface getCurrentReadSurface()
180 {
181     Current *current = GetCurrentData();
182 
183     return current->readSurface;
184 }
185 
error(EGLint errorCode)186 void error(EGLint errorCode)
187 {
188     egl::setCurrentError(errorCode);
189 }
190 
191 }
192