OSDN Git Service

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