OSDN Git Service

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