OSDN Git Service

Access library dependencies through a single object.
[android-x86/external-swiftshader.git] / src / OpenGL / libEGL / main.cpp
1 // SwiftShader Software Renderer\r
2 //\r
3 // Copyright(c) 2005-2013 TransGaming Inc.\r
4 //\r
5 // All rights reserved. No part of this software may be copied, distributed, transmitted,\r
6 // transcribed, stored in a retrieval system, translated into any human or computer\r
7 // language by any means, or disclosed to third parties without the explicit written\r
8 // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express\r
9 // or implied, including but not limited to any patent rights, are granted to you.\r
10 //\r
11 \r
12 // main.cpp: DLL entry point and management of thread-local data.\r
13 \r
14 #include "main.h"\r
15 \r
16 #include "libEGL.hpp"\r
17 #include "Context.hpp"\r
18 #include "Surface.h"\r
19 \r
20 #include "resource.h"\r
21 #include "Common/Thread.hpp"\r
22 #include "Common/SharedLibrary.hpp"\r
23 #include "common/debug.h"\r
24 \r
25 #define EGL_EGLEXT_PROTOTYPES\r
26 #include <EGL/eglext.h>\r
27 \r
28 static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;\r
29 \r
30 #if !defined(_MSC_VER)\r
31 #define CONSTRUCTOR __attribute__((constructor))\r
32 #define DESTRUCTOR __attribute__((destructor))\r
33 #else\r
34 #define CONSTRUCTOR\r
35 #define DESTRUCTOR\r
36 #endif\r
37 \r
38 static void eglAttachThread()\r
39 {\r
40     TRACE("()");\r
41 \r
42     egl::Current *current = new egl::Current;\r
43 \r
44     if(current)\r
45     {\r
46         sw::Thread::setLocalStorage(currentTLS, current);\r
47 \r
48         current->error = EGL_SUCCESS;\r
49         current->API = EGL_OPENGL_ES_API;\r
50                 current->display = nullptr;\r
51                 current->context = nullptr;\r
52                 current->drawSurface = nullptr;\r
53         current->readSurface = nullptr;\r
54         }\r
55 }\r
56 \r
57 static void eglDetachThread()\r
58 {\r
59     TRACE("()");\r
60 \r
61         egl::Current *current = (egl::Current*)sw::Thread::getLocalStorage(currentTLS);\r
62 \r
63         if(current)\r
64         {\r
65         delete current;\r
66         }\r
67 }\r
68 \r
69 CONSTRUCTOR static void eglAttachProcess()\r
70 {\r
71     TRACE("()");\r
72 \r
73         #if !defined(ANGLE_DISABLE_TRACE)\r
74         FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");\r
75 \r
76         if(debug)\r
77         {\r
78             fclose(debug);\r
79             debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase\r
80             fclose(debug);\r
81         }\r
82         #endif\r
83 \r
84     currentTLS = sw::Thread::allocateLocalStorageKey();\r
85 \r
86     if(currentTLS == TLS_OUT_OF_INDEXES)\r
87     {\r
88         return;\r
89     }\r
90 \r
91         eglAttachThread();\r
92 }\r
93 \r
94 DESTRUCTOR static void eglDetachProcess()\r
95 {\r
96     TRACE("()");\r
97 \r
98         eglDetachThread();\r
99         sw::Thread::freeLocalStorageKey(currentTLS);\r
100 }\r
101 \r
102 #if defined(_WIN32)\r
103 static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
104 {\r
105         RECT rect;\r
106 \r
107     switch(uMsg)\r
108     {\r
109     case WM_INITDIALOG:\r
110                 GetWindowRect(GetDesktopWindow(), &rect);\r
111                 SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);\r
112                 SetTimer(hwnd, 1, 100, NULL);\r
113                 return TRUE;\r
114     case WM_COMMAND:\r
115         if(LOWORD(wParam) == IDCANCEL)\r
116                 {\r
117                         EndDialog(hwnd, 0);\r
118                 }\r
119         break;\r
120     case WM_TIMER:\r
121                 if(IsDebuggerPresent())\r
122                 {\r
123                         EndDialog(hwnd, 0);\r
124                 }\r
125     }\r
126 \r
127     return FALSE;\r
128 }\r
129 \r
130 static void WaitForDebugger(HINSTANCE instance)\r
131 {\r
132     if(!IsDebuggerPresent())\r
133     {\r
134         HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);\r
135                 DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);\r
136                 DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);\r
137     }\r
138 }\r
139 \r
140 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)\r
141 {\r
142     switch(reason)\r
143     {\r
144     case DLL_PROCESS_ATTACH:\r
145                 #ifndef NDEBUG\r
146                         WaitForDebugger(instance);\r
147                 #endif\r
148         eglAttachProcess();\r
149         break;\r
150     case DLL_THREAD_ATTACH:\r
151         eglAttachThread();\r
152         break;\r
153     case DLL_THREAD_DETACH:\r
154         eglDetachThread();\r
155         break;\r
156     case DLL_PROCESS_DETACH:\r
157         eglDetachProcess();\r
158         break;\r
159     default:\r
160         break;\r
161     }\r
162 \r
163     return TRUE;\r
164 }\r
165 #endif\r
166 \r
167 namespace egl\r
168 {\r
169 static Current *eglGetCurrent(void)\r
170 {\r
171         Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);\r
172 \r
173         if(!current)\r
174         {\r
175                 eglAttachThread();\r
176         }\r
177 \r
178         return (Current*)sw::Thread::getLocalStorage(currentTLS);\r
179 }\r
180 \r
181 void setCurrentError(EGLint error)\r
182 {\r
183     Current *current = eglGetCurrent();\r
184 \r
185     current->error = error;\r
186 }\r
187 \r
188 EGLint getCurrentError()\r
189 {\r
190     Current *current = eglGetCurrent();\r
191 \r
192     return current->error;\r
193 }\r
194 \r
195 void setCurrentAPI(EGLenum API)\r
196 {\r
197     Current *current = eglGetCurrent();\r
198 \r
199     current->API = API;\r
200 }\r
201 \r
202 EGLenum getCurrentAPI()\r
203 {\r
204     Current *current = eglGetCurrent();\r
205 \r
206     return current->API;\r
207 }\r
208 \r
209 void setCurrentDisplay(egl::Display *dpy)\r
210 {\r
211     Current *current = eglGetCurrent();\r
212 \r
213     current->display = dpy;\r
214 }\r
215 \r
216 egl::Display *getCurrentDisplay()\r
217 {\r
218     Current *current = eglGetCurrent();\r
219 \r
220     return current->display;\r
221 }\r
222 \r
223 void setCurrentContext(egl::Context *ctx)\r
224 {\r
225     Current *current = eglGetCurrent();\r
226 \r
227         if(ctx)\r
228         {\r
229                 ctx->addRef();\r
230         }\r
231 \r
232         if(current->context)\r
233         {\r
234                 current->context->release();\r
235         }\r
236 \r
237     current->context = ctx;\r
238 }\r
239 \r
240 egl::Context *getCurrentContext()\r
241 {\r
242     Current *current = eglGetCurrent();\r
243 \r
244     return current->context;\r
245 }\r
246 \r
247 void setCurrentDrawSurface(egl::Surface *surface)\r
248 {\r
249     Current *current = eglGetCurrent();\r
250 \r
251         if(surface)\r
252         {\r
253                 surface->addRef();\r
254         }\r
255 \r
256         if(current->drawSurface)\r
257         {\r
258                 current->drawSurface->release();\r
259         }\r
260 \r
261     current->drawSurface = surface;\r
262 }\r
263 \r
264 egl::Surface *getCurrentDrawSurface()\r
265 {\r
266     Current *current = eglGetCurrent();\r
267 \r
268     return current->drawSurface;\r
269 }\r
270 \r
271 void setCurrentReadSurface(egl::Surface *surface)\r
272 {\r
273     Current *current = eglGetCurrent();\r
274 \r
275         if(surface)\r
276         {\r
277                 surface->addRef();\r
278         }\r
279 \r
280         if(current->readSurface)\r
281         {\r
282                 current->readSurface->release();\r
283         }\r
284 \r
285     current->readSurface = surface;\r
286 }\r
287 \r
288 egl::Surface *getCurrentReadSurface()\r
289 {\r
290     Current *current = eglGetCurrent();\r
291 \r
292     return current->readSurface;\r
293 }\r
294 \r
295 void error(EGLint errorCode)\r
296 {\r
297     egl::setCurrentError(errorCode);\r
298 \r
299         if(errorCode != EGL_SUCCESS)\r
300         {\r
301                 switch(errorCode)\r
302                 {\r
303                 case EGL_NOT_INITIALIZED:     TRACE("\t! Error generated: not initialized\n");     break;\r
304                 case EGL_BAD_ACCESS:          TRACE("\t! Error generated: bad access\n");          break;\r
305                 case EGL_BAD_ALLOC:           TRACE("\t! Error generated: bad alloc\n");           break;\r
306                 case EGL_BAD_ATTRIBUTE:       TRACE("\t! Error generated: bad attribute\n");       break;\r
307                 case EGL_BAD_CONFIG:          TRACE("\t! Error generated: bad config\n");          break;\r
308                 case EGL_BAD_CONTEXT:         TRACE("\t! Error generated: bad context\n");         break;\r
309                 case EGL_BAD_CURRENT_SURFACE: TRACE("\t! Error generated: bad current surface\n"); break;\r
310                 case EGL_BAD_DISPLAY:         TRACE("\t! Error generated: bad display\n");         break;\r
311                 case EGL_BAD_MATCH:           TRACE("\t! Error generated: bad match\n");           break;\r
312                 case EGL_BAD_NATIVE_PIXMAP:   TRACE("\t! Error generated: bad native pixmap\n");   break;\r
313                 case EGL_BAD_NATIVE_WINDOW:   TRACE("\t! Error generated: bad native window\n");   break;\r
314                 case EGL_BAD_PARAMETER:       TRACE("\t! Error generated: bad parameter\n");       break;\r
315                 case EGL_BAD_SURFACE:         TRACE("\t! Error generated: bad surface\n");         break;\r
316                 case EGL_CONTEXT_LOST:        TRACE("\t! Error generated: context lost\n");        break;\r
317                 default:                      TRACE("\t! Error generated: <0x%X>\n", errorCode);   break;\r
318                 }\r
319         }\r
320 }\r
321 }\r
322 \r
323 LibEGLexports::LibEGLexports()\r
324 {\r
325         this->eglGetError = ::eglGetError;\r
326         this->eglGetDisplay = ::eglGetDisplay;\r
327         this->eglInitialize = ::eglInitialize;\r
328         this->eglTerminate = ::eglTerminate;\r
329         this->eglQueryString = ::eglQueryString;\r
330         this->eglGetConfigs = ::eglGetConfigs;\r
331         this->eglChooseConfig = ::eglChooseConfig;\r
332         this->eglGetConfigAttrib = ::eglGetConfigAttrib;\r
333         this->eglCreateWindowSurface = ::eglCreateWindowSurface;\r
334         this->eglCreatePbufferSurface = ::eglCreatePbufferSurface;\r
335         this->eglCreatePixmapSurface = ::eglCreatePixmapSurface;\r
336         this->eglDestroySurface = ::eglDestroySurface;\r
337         this->eglQuerySurface = ::eglQuerySurface;\r
338         this->eglBindAPI = ::eglBindAPI;\r
339         this->eglQueryAPI = ::eglQueryAPI;\r
340         this->eglWaitClient = ::eglWaitClient;\r
341         this->eglReleaseThread = ::eglReleaseThread;\r
342         this->eglCreatePbufferFromClientBuffer = ::eglCreatePbufferFromClientBuffer;\r
343         this->eglSurfaceAttrib = ::eglSurfaceAttrib;\r
344         this->eglBindTexImage = ::eglBindTexImage;\r
345         this->eglReleaseTexImage = ::eglReleaseTexImage;\r
346         this->eglSwapInterval = ::eglSwapInterval;\r
347         this->eglCreateContext = ::eglCreateContext;\r
348         this->eglDestroyContext = ::eglDestroyContext;\r
349         this->eglMakeCurrent = ::eglMakeCurrent;\r
350         this->eglGetCurrentContext = ::eglGetCurrentContext;\r
351         this->eglGetCurrentSurface = ::eglGetCurrentSurface;\r
352         this->eglGetCurrentDisplay = ::eglGetCurrentDisplay;\r
353         this->eglQueryContext = ::eglQueryContext;\r
354         this->eglWaitGL = ::eglWaitGL;\r
355         this->eglWaitNative = ::eglWaitNative;\r
356         this->eglSwapBuffers = ::eglSwapBuffers;\r
357         this->eglCopyBuffers = ::eglCopyBuffers;\r
358         this->eglCreateImageKHR = ::eglCreateImageKHR;\r
359         this->eglDestroyImageKHR = ::eglDestroyImageKHR;\r
360         this->eglGetProcAddress = ::eglGetProcAddress;\r
361 \r
362         this->clientGetCurrentContext = egl::getCurrentContext;\r
363         this->clientGetCurrentDisplay = egl::getCurrentDisplay;\r
364 }\r
365 \r
366 extern "C" LibEGLexports *libEGLexports()\r
367 {\r
368         static LibEGLexports libEGL;\r
369         return &libEGL;\r
370 }\r
371 \r
372 LibGLES_CM libGLES_CM;\r
373 LibGLESv2 libGLESv2;\r