OSDN Git Service

Create 64-bit translator libraries for the Android Emulator.
[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 "resource.h"\r
17 #include "Common/Thread.hpp"\r
18 #include "Common/SharedLibrary.hpp"\r
19 #include "common/debug.h"\r
20 \r
21 static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;\r
22 \r
23 #if !defined(_MSC_VER)\r
24 #define CONSTRUCTOR __attribute__((constructor))\r
25 #define DESTRUCTOR __attribute__((destructor))\r
26 #else\r
27 #define CONSTRUCTOR\r
28 #define DESTRUCTOR\r
29 #endif\r
30 \r
31 static void eglAttachThread()\r
32 {\r
33     TRACE("()");\r
34 \r
35     egl::Current *current = new egl::Current;\r
36 \r
37     if(current)\r
38     {\r
39         sw::Thread::setLocalStorage(currentTLS, current);\r
40 \r
41         current->error = EGL_SUCCESS;\r
42         current->API = EGL_OPENGL_ES_API;\r
43         current->display = EGL_NO_DISPLAY;\r
44         current->drawSurface = EGL_NO_SURFACE;\r
45         current->readSurface = EGL_NO_SURFACE;\r
46                 current->context = EGL_NO_CONTEXT;\r
47         }\r
48 }\r
49 \r
50 static void eglDetachThread()\r
51 {\r
52     TRACE("()");\r
53 \r
54         egl::Current *current = (egl::Current*)sw::Thread::getLocalStorage(currentTLS);\r
55 \r
56         if(current)\r
57         {\r
58         delete current;\r
59         }\r
60 }\r
61 \r
62 CONSTRUCTOR static bool eglAttachProcess()\r
63 {\r
64     TRACE("()");\r
65 \r
66         #if !defined(ANGLE_DISABLE_TRACE)\r
67         FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");\r
68 \r
69         if(debug)\r
70         {\r
71             fclose(debug);\r
72             debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase\r
73             fclose(debug);\r
74         }\r
75         #endif\r
76 \r
77     currentTLS = sw::Thread::allocateLocalStorageKey();\r
78 \r
79     if(currentTLS == TLS_OUT_OF_INDEXES)\r
80     {\r
81         return false;\r
82     }\r
83 \r
84         eglAttachThread();\r
85 \r
86         #if defined(_WIN32)\r
87         const char *libGLES_CM_lib[] = {"libGLES_CM.dll", "libGLES_CM_translator.dll"};\r
88         #elif defined(__LP64__)\r
89         const char *libGLES_CM_lib[] = {"lib64GLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};\r
90         #else\r
91         const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};\r
92         #endif\r
93 \r
94     libGLES_CM = loadLibrary(libGLES_CM_lib);\r
95     es1::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*))getProcAddress(libGLES_CM, "glCreateContext");\r
96     es1::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLES_CM, "glGetProcAddress");\r
97 \r
98         #if defined(_WIN32)\r
99         const char *libGLESv2_lib[] = {"libGLESv2.dll", "libGLES_V2_translator.dll"};\r
100         #elif defined(__LP64__)\r
101         const char *libGLESv2_lib[] = {"lib64GLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};\r
102         #else\r
103         const char *libGLESv2_lib[] = {"libGLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};\r
104         #endif\r
105 \r
106     libGLESv2 = loadLibrary(libGLESv2_lib);\r
107     es2::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*))getProcAddress(libGLESv2, "glCreateContext");\r
108     es2::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLESv2, "glGetProcAddress");\r
109 \r
110         es::createBackBuffer = (egl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLES_CM, "createBackBuffer");\r
111         es::createDepthStencil = (egl::Image *(*)(unsigned int, unsigned int, sw::Format, int, bool))getProcAddress(libGLES_CM, "createDepthStencil");\r
112     es::createFrameBuffer = (sw::FrameBuffer *(*)(EGLNativeDisplayType, EGLNativeWindowType, int, int))getProcAddress(libGLES_CM, "createFrameBuffer");\r
113 \r
114         if(!es::createBackBuffer)\r
115         {\r
116                 es::createBackBuffer = (egl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLESv2, "createBackBuffer");\r
117                 es::createDepthStencil = (egl::Image *(*)(unsigned int, unsigned int, sw::Format, int, bool))getProcAddress(libGLESv2, "createDepthStencil");\r
118                 es::createFrameBuffer = (sw::FrameBuffer *(*)(EGLNativeDisplayType, EGLNativeWindowType, int, int))getProcAddress(libGLESv2, "createFrameBuffer");\r
119         }\r
120 \r
121         return libGLES_CM != 0 || libGLESv2 != 0;\r
122 }\r
123 \r
124 DESTRUCTOR static void eglDetachProcess()\r
125 {\r
126     TRACE("()");\r
127 \r
128         eglDetachThread();\r
129         sw::Thread::freeLocalStorageKey(currentTLS);\r
130         freeLibrary(libGLESv2);\r
131 }\r
132 \r
133 #if defined(_WIN32)\r
134 static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
135 {\r
136         RECT rect;\r
137 \r
138     switch(uMsg)\r
139     {\r
140     case WM_INITDIALOG:\r
141                 GetWindowRect(GetDesktopWindow(), &rect);\r
142                 SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);\r
143                 SetTimer(hwnd, 1, 100, NULL);\r
144                 return TRUE;\r
145     case WM_COMMAND:\r
146         if(LOWORD(wParam) == IDCANCEL)\r
147                 {\r
148                         EndDialog(hwnd, 0);\r
149                 }\r
150         break;\r
151     case WM_TIMER:\r
152                 if(IsDebuggerPresent())\r
153                 {\r
154                         EndDialog(hwnd, 0);\r
155                 }\r
156     }\r
157 \r
158     return FALSE;\r
159 }\r
160 \r
161 static void WaitForDebugger(HINSTANCE instance)\r
162 {\r
163     if(!IsDebuggerPresent())\r
164     {\r
165         HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);\r
166                 DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);\r
167                 DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);\r
168     }\r
169 }\r
170 \r
171 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)\r
172 {\r
173     switch(reason)\r
174     {\r
175     case DLL_PROCESS_ATTACH:\r
176                 if(false)\r
177                 {\r
178                         WaitForDebugger(instance);\r
179                 }\r
180         return eglAttachProcess();\r
181         break;\r
182     case DLL_THREAD_ATTACH:\r
183         eglAttachThread();\r
184         break;\r
185     case DLL_THREAD_DETACH:\r
186         eglDetachThread();\r
187         break;\r
188     case DLL_PROCESS_DETACH:\r
189         eglDetachProcess();\r
190         break;\r
191     default:\r
192         break;\r
193     }\r
194 \r
195     return TRUE;\r
196 }\r
197 #endif\r
198 \r
199 namespace egl\r
200 {\r
201 static Current *eglGetCurrent(void)\r
202 {\r
203         Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);\r
204 \r
205         if(!current)\r
206         {\r
207                 eglAttachThread();\r
208         }\r
209 \r
210         return (Current*)sw::Thread::getLocalStorage(currentTLS);\r
211 }\r
212 \r
213 void setCurrentError(EGLint error)\r
214 {\r
215     Current *current = eglGetCurrent();\r
216 \r
217     current->error = error;\r
218 }\r
219 \r
220 EGLint getCurrentError()\r
221 {\r
222     Current *current = eglGetCurrent();\r
223 \r
224     return current->error;\r
225 }\r
226 \r
227 void setCurrentAPI(EGLenum API)\r
228 {\r
229     Current *current = eglGetCurrent();\r
230 \r
231     current->API = API;\r
232 }\r
233 \r
234 EGLenum getCurrentAPI()\r
235 {\r
236     Current *current = eglGetCurrent();\r
237 \r
238     return current->API;\r
239 }\r
240 \r
241 void setCurrentDisplay(EGLDisplay dpy)\r
242 {\r
243     Current *current = eglGetCurrent();\r
244 \r
245     current->display = dpy;\r
246 }\r
247 \r
248 EGLDisplay getCurrentDisplay()\r
249 {\r
250     Current *current = eglGetCurrent();\r
251 \r
252     return current->display;\r
253 }\r
254 \r
255 void setCurrentContext(EGLContext ctx)\r
256 {\r
257     Current *current = eglGetCurrent();\r
258 \r
259     current->context = ctx;\r
260 }\r
261 \r
262 EGLContext getCurrentContext()\r
263 {\r
264     Current *current = eglGetCurrent();\r
265 \r
266     return current->context;\r
267 }\r
268 \r
269 void setCurrentDrawSurface(EGLSurface surface)\r
270 {\r
271     Current *current = eglGetCurrent();\r
272 \r
273     current->drawSurface = surface;\r
274 }\r
275 \r
276 EGLSurface getCurrentDrawSurface()\r
277 {\r
278     Current *current = eglGetCurrent();\r
279 \r
280     return current->drawSurface;\r
281 }\r
282 \r
283 void setCurrentReadSurface(EGLSurface surface)\r
284 {\r
285     Current *current = eglGetCurrent();\r
286 \r
287     current->readSurface = surface;\r
288 }\r
289 \r
290 EGLSurface getCurrentReadSurface()\r
291 {\r
292     Current *current = eglGetCurrent();\r
293 \r
294     return current->readSurface;\r
295 }\r
296 }\r
297 \r
298 void error(EGLint errorCode)\r
299 {\r
300     egl::setCurrentError(errorCode);\r
301 \r
302         if(errorCode != EGL_SUCCESS)\r
303         {\r
304                 switch(errorCode)\r
305                 {\r
306                 case EGL_NOT_INITIALIZED:     TRACE("\t! Error generated: not initialized\n");     break;\r
307                 case EGL_BAD_ACCESS:          TRACE("\t! Error generated: bad access\n");          break;\r
308                 case EGL_BAD_ALLOC:           TRACE("\t! Error generated: bad alloc\n");           break;\r
309                 case EGL_BAD_ATTRIBUTE:       TRACE("\t! Error generated: bad attribute\n");       break;\r
310                 case EGL_BAD_CONFIG:          TRACE("\t! Error generated: bad config\n");          break;\r
311                 case EGL_BAD_CONTEXT:         TRACE("\t! Error generated: bad context\n");         break;\r
312                 case EGL_BAD_CURRENT_SURFACE: TRACE("\t! Error generated: bad current surface\n"); break;\r
313                 case EGL_BAD_DISPLAY:         TRACE("\t! Error generated: bad display\n");         break;\r
314                 case EGL_BAD_MATCH:           TRACE("\t! Error generated: bad match\n");           break;\r
315                 case EGL_BAD_NATIVE_PIXMAP:   TRACE("\t! Error generated: bad native pixmap\n");   break;\r
316                 case EGL_BAD_NATIVE_WINDOW:   TRACE("\t! Error generated: bad native window\n");   break;\r
317                 case EGL_BAD_PARAMETER:       TRACE("\t! Error generated: bad parameter\n");       break;\r
318                 case EGL_BAD_SURFACE:         TRACE("\t! Error generated: bad surface\n");         break;\r
319                 case EGL_CONTEXT_LOST:        TRACE("\t! Error generated: context lost\n");        break;\r
320                 default:                      TRACE("\t! Error generated: <0x%X>\n", errorCode);   break;\r
321                 }\r
322         }\r
323 }\r
324 \r
325 extern "C"\r
326 {\r
327 EGLContext clientGetCurrentContext()\r
328 {\r
329     return egl::getCurrentContext();\r
330 }\r
331 \r
332 EGLContext clientGetCurrentDisplay()\r
333 {\r
334     return egl::getCurrentDisplay();\r
335 }\r
336 }\r
337 \r
338 namespace es1\r
339 {\r
340         egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;\r
341         __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;\r
342 }\r
343 \r
344 namespace es2\r
345 {\r
346         egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;\r
347         __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;\r
348 }\r
349 \r
350 namespace es\r
351 {\r
352         egl::Image *(*createBackBuffer)(int width, int height, const egl::Config *config) = 0;\r
353         egl::Image *(*createDepthStencil)(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard) = 0;\r
354         sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height) = 0;\r
355 }\r
356 \r
357 void *libGLES_CM = 0;   // Handle to the libGLES_CM module\r
358 void *libGLESv2 = 0;   // Handle to the libGLESv2 module\r