1 // SwiftShader Software Renderer
\r
3 // Copyright(c) 2005-2013 TransGaming Inc.
\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
12 // main.cpp: DLL entry point and management of thread-local data.
\r
16 #include "resource.h"
\r
17 #include "Common/Thread.hpp"
\r
18 #include "Common/SharedLibrary.hpp"
\r
19 #include "common/debug.h"
\r
21 static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
\r
23 #if !defined(_MSC_VER)
\r
24 #define CONSTRUCTOR __attribute__((constructor))
\r
25 #define DESTRUCTOR __attribute__((destructor))
\r
31 static void eglAttachThread()
\r
35 egl::Current *current = new egl::Current;
\r
39 sw::Thread::setLocalStorage(currentTLS, current);
\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
50 static void eglDetachThread()
\r
54 egl::Current *current = (egl::Current*)sw::Thread::getLocalStorage(currentTLS);
\r
62 CONSTRUCTOR static bool eglAttachProcess()
\r
66 #if !defined(ANGLE_DISABLE_TRACE)
\r
67 FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
\r
72 debug = fopen(TRACE_OUTPUT_FILE, "wt"); // Erase
\r
77 currentTLS = sw::Thread::allocateLocalStorageKey();
\r
79 if(currentTLS == TLS_OUT_OF_INDEXES)
\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
93 const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
\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
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
107 const char *libGLESv2_lib[] = {"libGLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
\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
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
118 if(!es::createBackBuffer)
\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
125 return libGLES_CM != 0 || libGLESv2 != 0;
\r
128 DESTRUCTOR static void eglDetachProcess()
\r
133 sw::Thread::freeLocalStorageKey(currentTLS);
\r
134 freeLibrary(libGLESv2);
\r
137 #if defined(_WIN32)
\r
138 static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
\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
150 if(LOWORD(wParam) == IDCANCEL)
\r
152 EndDialog(hwnd, 0);
\r
156 if(IsDebuggerPresent())
\r
158 EndDialog(hwnd, 0);
\r
165 static void WaitForDebugger(HINSTANCE instance)
\r
167 if(!IsDebuggerPresent())
\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
175 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
\r
179 case DLL_PROCESS_ATTACH:
\r
181 WaitForDebugger(instance);
\r
183 return eglAttachProcess();
\r
185 case DLL_THREAD_ATTACH:
\r
188 case DLL_THREAD_DETACH:
\r
191 case DLL_PROCESS_DETACH:
\r
192 eglDetachProcess();
\r
204 static Current *eglGetCurrent(void)
\r
206 Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
\r
213 return (Current*)sw::Thread::getLocalStorage(currentTLS);
\r
216 void setCurrentError(EGLint error)
\r
218 Current *current = eglGetCurrent();
\r
220 current->error = error;
\r
223 EGLint getCurrentError()
\r
225 Current *current = eglGetCurrent();
\r
227 return current->error;
\r
230 void setCurrentAPI(EGLenum API)
\r
232 Current *current = eglGetCurrent();
\r
234 current->API = API;
\r
237 EGLenum getCurrentAPI()
\r
239 Current *current = eglGetCurrent();
\r
241 return current->API;
\r
244 void setCurrentDisplay(EGLDisplay dpy)
\r
246 Current *current = eglGetCurrent();
\r
248 current->display = dpy;
\r
251 EGLDisplay getCurrentDisplay()
\r
253 Current *current = eglGetCurrent();
\r
255 return current->display;
\r
258 void setCurrentContext(EGLContext ctx)
\r
260 Current *current = eglGetCurrent();
\r
262 current->context = ctx;
\r
265 EGLContext getCurrentContext()
\r
267 Current *current = eglGetCurrent();
\r
269 return current->context;
\r
272 void setCurrentDrawSurface(EGLSurface surface)
\r
274 Current *current = eglGetCurrent();
\r
276 current->drawSurface = surface;
\r
279 EGLSurface getCurrentDrawSurface()
\r
281 Current *current = eglGetCurrent();
\r
283 return current->drawSurface;
\r
286 void setCurrentReadSurface(EGLSurface surface)
\r
288 Current *current = eglGetCurrent();
\r
290 current->readSurface = surface;
\r
293 EGLSurface getCurrentReadSurface()
\r
295 Current *current = eglGetCurrent();
\r
297 return current->readSurface;
\r
301 void error(EGLint errorCode)
\r
303 egl::setCurrentError(errorCode);
\r
305 if(errorCode != EGL_SUCCESS)
\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
330 EGLContext clientGetCurrentContext()
\r
332 return egl::getCurrentContext();
\r
335 EGLContext clientGetCurrentDisplay()
\r
337 return egl::getCurrentDisplay();
\r
343 egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;
\r
344 __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;
\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
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
360 void *libGLES_CM = 0; // Handle to the libGLES_CM module
\r
361 void *libGLESv2 = 0; // Handle to the libGLESv2 module
\r