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 "Context.hpp"
\r
17 #include "Surface.h"
\r
19 #include "resource.h"
\r
20 #include "Common/Thread.hpp"
\r
21 #include "Common/SharedLibrary.hpp"
\r
22 #include "common/debug.h"
\r
24 static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
\r
26 #if !defined(_MSC_VER)
\r
27 #define CONSTRUCTOR __attribute__((constructor))
\r
28 #define DESTRUCTOR __attribute__((destructor))
\r
34 static void eglAttachThread()
\r
38 egl::Current *current = new egl::Current;
\r
42 sw::Thread::setLocalStorage(currentTLS, current);
\r
44 current->error = EGL_SUCCESS;
\r
45 current->API = EGL_OPENGL_ES_API;
\r
46 current->display = nullptr;
\r
47 current->context = nullptr;
\r
48 current->drawSurface = nullptr;
\r
49 current->readSurface = nullptr;
\r
53 static void eglDetachThread()
\r
57 egl::Current *current = (egl::Current*)sw::Thread::getLocalStorage(currentTLS);
\r
65 CONSTRUCTOR static bool eglAttachProcess()
\r
69 #if !defined(ANGLE_DISABLE_TRACE)
\r
70 FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
\r
75 debug = fopen(TRACE_OUTPUT_FILE, "wt"); // Erase
\r
80 currentTLS = sw::Thread::allocateLocalStorageKey();
\r
82 if(currentTLS == TLS_OUT_OF_INDEXES)
\r
90 const char *libGLES_CM_lib[] = {"libGLES_CM.dll", "libGLES_CM_translator.dll"};
\r
91 #elif defined(__ANDROID__)
\r
92 const char *libGLES_CM_lib[] = {"/vendor/lib/egl/libGLESv1_CM_swiftshader.so"};
\r
93 #elif defined(__LP64__)
\r
94 const char *libGLES_CM_lib[] = {"lib64GLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
\r
96 const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
\r
99 libGLES_CM = loadLibrary(libGLES_CM_lib);
\r
100 es1::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*))getProcAddress(libGLES_CM, "glCreateContext");
\r
101 es1::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLES_CM, "glGetProcAddress");
\r
103 #if defined(_WIN32)
\r
104 const char *libGLESv2_lib[] = {"libGLESv2.dll", "libGLES_V2_translator.dll"};
\r
105 #elif defined(__ANDROID__)
\r
106 const char *libGLESv2_lib[] = {"/vendor/lib/egl/libGLESv2_swiftshader.so"};
\r
107 #elif defined(__LP64__)
\r
108 const char *libGLESv2_lib[] = {"lib64GLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
\r
110 const char *libGLESv2_lib[] = {"libGLES_V2_translator.so", "libGLESv2.so.2", "libGLESv2.so"};
\r
113 libGLESv2 = loadLibrary(libGLESv2_lib);
\r
114 es2::createContext = (egl::Context *(*)(const egl::Config*, const egl::Context*, EGLint))getProcAddress(libGLESv2, "glCreateContext");
\r
115 es2::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLESv2, "glGetProcAddress");
\r
117 es::createBackBuffer = (egl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLES_CM, "createBackBuffer");
\r
118 es::createDepthStencil = (egl::Image *(*)(unsigned int, unsigned int, sw::Format, int, bool))getProcAddress(libGLES_CM, "createDepthStencil");
\r
119 es::createFrameBuffer = (sw::FrameBuffer *(*)(EGLNativeDisplayType, EGLNativeWindowType, int, int))getProcAddress(libGLES_CM, "createFrameBuffer");
\r
121 if(!es::createBackBuffer)
\r
123 es::createBackBuffer = (egl::Image *(*)(int, int, const egl::Config*))getProcAddress(libGLESv2, "createBackBuffer");
\r
124 es::createDepthStencil = (egl::Image *(*)(unsigned int, unsigned int, sw::Format, int, bool))getProcAddress(libGLESv2, "createDepthStencil");
\r
125 es::createFrameBuffer = (sw::FrameBuffer *(*)(EGLNativeDisplayType, EGLNativeWindowType, int, int))getProcAddress(libGLESv2, "createFrameBuffer");
\r
128 return libGLES_CM != 0 || libGLESv2 != 0;
\r
131 DESTRUCTOR static void eglDetachProcess()
\r
136 sw::Thread::freeLocalStorageKey(currentTLS);
\r
137 freeLibrary(libGLESv2);
\r
140 #if defined(_WIN32)
\r
141 static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
147 case WM_INITDIALOG:
\r
148 GetWindowRect(GetDesktopWindow(), &rect);
\r
149 SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
\r
150 SetTimer(hwnd, 1, 100, NULL);
\r
153 if(LOWORD(wParam) == IDCANCEL)
\r
155 EndDialog(hwnd, 0);
\r
159 if(IsDebuggerPresent())
\r
161 EndDialog(hwnd, 0);
\r
168 static void WaitForDebugger(HINSTANCE instance)
\r
170 if(!IsDebuggerPresent())
\r
172 HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
\r
173 DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);
\r
174 DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
\r
178 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
\r
182 case DLL_PROCESS_ATTACH:
\r
184 WaitForDebugger(instance);
\r
186 return eglAttachProcess();
\r
188 case DLL_THREAD_ATTACH:
\r
191 case DLL_THREAD_DETACH:
\r
194 case DLL_PROCESS_DETACH:
\r
195 eglDetachProcess();
\r
207 static Current *eglGetCurrent(void)
\r
209 Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
\r
216 return (Current*)sw::Thread::getLocalStorage(currentTLS);
\r
219 void setCurrentError(EGLint error)
\r
221 Current *current = eglGetCurrent();
\r
223 current->error = error;
\r
226 EGLint getCurrentError()
\r
228 Current *current = eglGetCurrent();
\r
230 return current->error;
\r
233 void setCurrentAPI(EGLenum API)
\r
235 Current *current = eglGetCurrent();
\r
237 current->API = API;
\r
240 EGLenum getCurrentAPI()
\r
242 Current *current = eglGetCurrent();
\r
244 return current->API;
\r
247 void setCurrentDisplay(egl::Display *dpy)
\r
249 Current *current = eglGetCurrent();
\r
251 current->display = dpy;
\r
254 egl::Display *getCurrentDisplay()
\r
256 Current *current = eglGetCurrent();
\r
258 return current->display;
\r
261 void setCurrentContext(egl::Context *ctx)
\r
263 Current *current = eglGetCurrent();
\r
270 if(current->context)
\r
272 current->context->release();
\r
275 current->context = ctx;
\r
278 egl::Context *getCurrentContext()
\r
280 Current *current = eglGetCurrent();
\r
282 return current->context;
\r
285 void setCurrentDrawSurface(egl::Surface *surface)
\r
287 Current *current = eglGetCurrent();
\r
294 if(current->drawSurface)
\r
296 current->drawSurface->release();
\r
299 current->drawSurface = surface;
\r
302 egl::Surface *getCurrentDrawSurface()
\r
304 Current *current = eglGetCurrent();
\r
306 return current->drawSurface;
\r
309 void setCurrentReadSurface(egl::Surface *surface)
\r
311 Current *current = eglGetCurrent();
\r
318 if(current->readSurface)
\r
320 current->readSurface->release();
\r
323 current->readSurface = surface;
\r
326 egl::Surface *getCurrentReadSurface()
\r
328 Current *current = eglGetCurrent();
\r
330 return current->readSurface;
\r
334 void error(EGLint errorCode)
\r
336 egl::setCurrentError(errorCode);
\r
338 if(errorCode != EGL_SUCCESS)
\r
342 case EGL_NOT_INITIALIZED: TRACE("\t! Error generated: not initialized\n"); break;
\r
343 case EGL_BAD_ACCESS: TRACE("\t! Error generated: bad access\n"); break;
\r
344 case EGL_BAD_ALLOC: TRACE("\t! Error generated: bad alloc\n"); break;
\r
345 case EGL_BAD_ATTRIBUTE: TRACE("\t! Error generated: bad attribute\n"); break;
\r
346 case EGL_BAD_CONFIG: TRACE("\t! Error generated: bad config\n"); break;
\r
347 case EGL_BAD_CONTEXT: TRACE("\t! Error generated: bad context\n"); break;
\r
348 case EGL_BAD_CURRENT_SURFACE: TRACE("\t! Error generated: bad current surface\n"); break;
\r
349 case EGL_BAD_DISPLAY: TRACE("\t! Error generated: bad display\n"); break;
\r
350 case EGL_BAD_MATCH: TRACE("\t! Error generated: bad match\n"); break;
\r
351 case EGL_BAD_NATIVE_PIXMAP: TRACE("\t! Error generated: bad native pixmap\n"); break;
\r
352 case EGL_BAD_NATIVE_WINDOW: TRACE("\t! Error generated: bad native window\n"); break;
\r
353 case EGL_BAD_PARAMETER: TRACE("\t! Error generated: bad parameter\n"); break;
\r
354 case EGL_BAD_SURFACE: TRACE("\t! Error generated: bad surface\n"); break;
\r
355 case EGL_CONTEXT_LOST: TRACE("\t! Error generated: context lost\n"); break;
\r
356 default: TRACE("\t! Error generated: <0x%X>\n", errorCode); break;
\r
363 EGLContext clientGetCurrentContext()
\r
365 return egl::getCurrentContext();
\r
368 EGLContext clientGetCurrentDisplay()
\r
370 return egl::getCurrentDisplay();
\r
376 egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext) = 0;
\r
377 __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;
\r
382 egl::Context *(*createContext)(const egl::Config *config, const egl::Context *shareContext, EGLint clientVersion) = 0;
\r
383 __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;
\r
388 egl::Image *(*createBackBuffer)(int width, int height, const egl::Config *config) = 0;
\r
389 egl::Image *(*createDepthStencil)(unsigned int width, unsigned int height, sw::Format format, int multiSampleDepth, bool discard) = 0;
\r
390 sw::FrameBuffer *(*createFrameBuffer)(EGLNativeDisplayType display, EGLNativeWindowType window, int width, int height) = 0;
\r
393 void *libGLES_CM = 0; // Handle to the libGLES_CM module
\r
394 void *libGLESv2 = 0; // Handle to the libGLESv2 module
\r