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
89 const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
\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
97 const char *libGLESv2_lib[] = {"libGLESv2.dll", "libGLES_V2_translator.dll"};
\r
99 const char *libGLESv2_lib[] = {"libGLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
\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
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
110 if(!es::createBackBuffer)
\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
117 return libGLES_CM != 0 || libGLESv2 != 0;
\r
120 DESTRUCTOR static void eglDetachProcess()
\r
125 sw::Thread::freeLocalStorageKey(currentTLS);
\r
126 freeLibrary(libGLESv2);
\r
129 #if defined(_WIN32)
\r
130 static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
\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
142 if(LOWORD(wParam) == IDCANCEL)
\r
144 EndDialog(hwnd, 0);
\r
148 if(IsDebuggerPresent())
\r
150 EndDialog(hwnd, 0);
\r
157 static void WaitForDebugger(HINSTANCE instance)
\r
159 if(!IsDebuggerPresent())
\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
167 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
\r
171 case DLL_PROCESS_ATTACH:
\r
174 WaitForDebugger(instance);
\r
176 return eglAttachProcess();
\r
178 case DLL_THREAD_ATTACH:
\r
181 case DLL_THREAD_DETACH:
\r
184 case DLL_PROCESS_DETACH:
\r
185 eglDetachProcess();
\r
197 static Current *eglGetCurrent(void)
\r
199 Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
\r
206 return (Current*)sw::Thread::getLocalStorage(currentTLS);
\r
209 void setCurrentError(EGLint error)
\r
211 Current *current = eglGetCurrent();
\r
213 current->error = error;
\r
216 EGLint getCurrentError()
\r
218 Current *current = eglGetCurrent();
\r
220 return current->error;
\r
223 void setCurrentAPI(EGLenum API)
\r
225 Current *current = eglGetCurrent();
\r
227 current->API = API;
\r
230 EGLenum getCurrentAPI()
\r
232 Current *current = eglGetCurrent();
\r
234 return current->API;
\r
237 void setCurrentDisplay(EGLDisplay dpy)
\r
239 Current *current = eglGetCurrent();
\r
241 current->display = dpy;
\r
244 EGLDisplay getCurrentDisplay()
\r
246 Current *current = eglGetCurrent();
\r
248 return current->display;
\r
251 void setCurrentContext(EGLContext ctx)
\r
253 Current *current = eglGetCurrent();
\r
255 current->context = ctx;
\r
258 EGLContext getCurrentContext()
\r
260 Current *current = eglGetCurrent();
\r
262 return current->context;
\r
265 void setCurrentDrawSurface(EGLSurface surface)
\r
267 Current *current = eglGetCurrent();
\r
269 current->drawSurface = surface;
\r
272 EGLSurface getCurrentDrawSurface()
\r
274 Current *current = eglGetCurrent();
\r
276 return current->drawSurface;
\r
279 void setCurrentReadSurface(EGLSurface surface)
\r
281 Current *current = eglGetCurrent();
\r
283 current->readSurface = surface;
\r
286 EGLSurface getCurrentReadSurface()
\r
288 Current *current = eglGetCurrent();
\r
290 return current->readSurface;
\r
294 void error(EGLint errorCode)
\r
296 egl::setCurrentError(errorCode);
\r
298 if(errorCode != EGL_SUCCESS)
\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
323 EGLContext clientGetCurrentContext()
\r
325 return egl::getCurrentContext();
\r
328 EGLContext clientGetCurrentDisplay()
\r
330 return egl::getCurrentDisplay();
\r
336 egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;
\r
337 __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;
\r
342 egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;
\r
343 __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;
\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
353 void *libGLES_CM = 0; // Handle to the libGLES_CM module
\r
354 void *libGLESv2 = 0; // Handle to the libGLESv2 module
\r