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 "libEGL.hpp"
\r
17 #include "Context.hpp"
\r
18 #include "Surface.h"
\r
20 #include "resource.h"
\r
21 #include "Common/Thread.hpp"
\r
22 #include "Common/SharedLibrary.hpp"
\r
23 #include "common/debug.h"
\r
25 #define EGL_EGLEXT_PROTOTYPES
\r
26 #include <EGL/eglext.h>
\r
28 static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
\r
30 #if !defined(_MSC_VER)
\r
31 #define CONSTRUCTOR __attribute__((constructor))
\r
32 #define DESTRUCTOR __attribute__((destructor))
\r
38 static void eglAttachThread()
\r
42 egl::Current *current = new egl::Current;
\r
46 sw::Thread::setLocalStorage(currentTLS, current);
\r
48 current->error = EGL_SUCCESS;
\r
49 current->API = EGL_OPENGL_ES_API;
\r
50 current->display = nullptr;
\r
51 current->context = nullptr;
\r
52 current->drawSurface = nullptr;
\r
53 current->readSurface = nullptr;
\r
57 static void eglDetachThread()
\r
61 egl::Current *current = (egl::Current*)sw::Thread::getLocalStorage(currentTLS);
\r
69 CONSTRUCTOR static void eglAttachProcess()
\r
73 #if !defined(ANGLE_DISABLE_TRACE)
\r
74 FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
\r
79 debug = fopen(TRACE_OUTPUT_FILE, "wt"); // Erase
\r
84 currentTLS = sw::Thread::allocateLocalStorageKey();
\r
86 if(currentTLS == TLS_OUT_OF_INDEXES)
\r
94 DESTRUCTOR static void eglDetachProcess()
\r
99 sw::Thread::freeLocalStorageKey(currentTLS);
\r
102 #if defined(_WIN32)
\r
103 static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
109 case WM_INITDIALOG:
\r
110 GetWindowRect(GetDesktopWindow(), &rect);
\r
111 SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
\r
112 SetTimer(hwnd, 1, 100, NULL);
\r
115 if(LOWORD(wParam) == IDCANCEL)
\r
117 EndDialog(hwnd, 0);
\r
121 if(IsDebuggerPresent())
\r
123 EndDialog(hwnd, 0);
\r
130 static void WaitForDebugger(HINSTANCE instance)
\r
132 if(!IsDebuggerPresent())
\r
134 HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
\r
135 DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);
\r
136 DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
\r
140 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
\r
144 case DLL_PROCESS_ATTACH:
\r
146 WaitForDebugger(instance);
\r
148 eglAttachProcess();
\r
150 case DLL_THREAD_ATTACH:
\r
153 case DLL_THREAD_DETACH:
\r
156 case DLL_PROCESS_DETACH:
\r
157 eglDetachProcess();
\r
169 static Current *eglGetCurrent(void)
\r
171 Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
\r
178 return (Current*)sw::Thread::getLocalStorage(currentTLS);
\r
181 void setCurrentError(EGLint error)
\r
183 Current *current = eglGetCurrent();
\r
185 current->error = error;
\r
188 EGLint getCurrentError()
\r
190 Current *current = eglGetCurrent();
\r
192 return current->error;
\r
195 void setCurrentAPI(EGLenum API)
\r
197 Current *current = eglGetCurrent();
\r
199 current->API = API;
\r
202 EGLenum getCurrentAPI()
\r
204 Current *current = eglGetCurrent();
\r
206 return current->API;
\r
209 void setCurrentDisplay(egl::Display *dpy)
\r
211 Current *current = eglGetCurrent();
\r
213 current->display = dpy;
\r
216 egl::Display *getCurrentDisplay()
\r
218 Current *current = eglGetCurrent();
\r
220 return current->display;
\r
223 void setCurrentContext(egl::Context *ctx)
\r
225 Current *current = eglGetCurrent();
\r
232 if(current->context)
\r
234 current->context->release();
\r
237 current->context = ctx;
\r
240 egl::Context *getCurrentContext()
\r
242 Current *current = eglGetCurrent();
\r
244 return current->context;
\r
247 void setCurrentDrawSurface(egl::Surface *surface)
\r
249 Current *current = eglGetCurrent();
\r
256 if(current->drawSurface)
\r
258 current->drawSurface->release();
\r
261 current->drawSurface = surface;
\r
264 egl::Surface *getCurrentDrawSurface()
\r
266 Current *current = eglGetCurrent();
\r
268 return current->drawSurface;
\r
271 void setCurrentReadSurface(egl::Surface *surface)
\r
273 Current *current = eglGetCurrent();
\r
280 if(current->readSurface)
\r
282 current->readSurface->release();
\r
285 current->readSurface = surface;
\r
288 egl::Surface *getCurrentReadSurface()
\r
290 Current *current = eglGetCurrent();
\r
292 return current->readSurface;
\r
295 void error(EGLint errorCode)
\r
297 egl::setCurrentError(errorCode);
\r
299 if(errorCode != EGL_SUCCESS)
\r
303 case EGL_NOT_INITIALIZED: TRACE("\t! Error generated: not initialized\n"); break;
\r
304 case EGL_BAD_ACCESS: TRACE("\t! Error generated: bad access\n"); break;
\r
305 case EGL_BAD_ALLOC: TRACE("\t! Error generated: bad alloc\n"); break;
\r
306 case EGL_BAD_ATTRIBUTE: TRACE("\t! Error generated: bad attribute\n"); break;
\r
307 case EGL_BAD_CONFIG: TRACE("\t! Error generated: bad config\n"); break;
\r
308 case EGL_BAD_CONTEXT: TRACE("\t! Error generated: bad context\n"); break;
\r
309 case EGL_BAD_CURRENT_SURFACE: TRACE("\t! Error generated: bad current surface\n"); break;
\r
310 case EGL_BAD_DISPLAY: TRACE("\t! Error generated: bad display\n"); break;
\r
311 case EGL_BAD_MATCH: TRACE("\t! Error generated: bad match\n"); break;
\r
312 case EGL_BAD_NATIVE_PIXMAP: TRACE("\t! Error generated: bad native pixmap\n"); break;
\r
313 case EGL_BAD_NATIVE_WINDOW: TRACE("\t! Error generated: bad native window\n"); break;
\r
314 case EGL_BAD_PARAMETER: TRACE("\t! Error generated: bad parameter\n"); break;
\r
315 case EGL_BAD_SURFACE: TRACE("\t! Error generated: bad surface\n"); break;
\r
316 case EGL_CONTEXT_LOST: TRACE("\t! Error generated: context lost\n"); break;
\r
317 default: TRACE("\t! Error generated: <0x%X>\n", errorCode); break;
\r
323 LibEGLexports::LibEGLexports()
\r
325 this->eglGetError = ::eglGetError;
\r
326 this->eglGetDisplay = ::eglGetDisplay;
\r
327 this->eglInitialize = ::eglInitialize;
\r
328 this->eglTerminate = ::eglTerminate;
\r
329 this->eglQueryString = ::eglQueryString;
\r
330 this->eglGetConfigs = ::eglGetConfigs;
\r
331 this->eglChooseConfig = ::eglChooseConfig;
\r
332 this->eglGetConfigAttrib = ::eglGetConfigAttrib;
\r
333 this->eglCreateWindowSurface = ::eglCreateWindowSurface;
\r
334 this->eglCreatePbufferSurface = ::eglCreatePbufferSurface;
\r
335 this->eglCreatePixmapSurface = ::eglCreatePixmapSurface;
\r
336 this->eglDestroySurface = ::eglDestroySurface;
\r
337 this->eglQuerySurface = ::eglQuerySurface;
\r
338 this->eglBindAPI = ::eglBindAPI;
\r
339 this->eglQueryAPI = ::eglQueryAPI;
\r
340 this->eglWaitClient = ::eglWaitClient;
\r
341 this->eglReleaseThread = ::eglReleaseThread;
\r
342 this->eglCreatePbufferFromClientBuffer = ::eglCreatePbufferFromClientBuffer;
\r
343 this->eglSurfaceAttrib = ::eglSurfaceAttrib;
\r
344 this->eglBindTexImage = ::eglBindTexImage;
\r
345 this->eglReleaseTexImage = ::eglReleaseTexImage;
\r
346 this->eglSwapInterval = ::eglSwapInterval;
\r
347 this->eglCreateContext = ::eglCreateContext;
\r
348 this->eglDestroyContext = ::eglDestroyContext;
\r
349 this->eglMakeCurrent = ::eglMakeCurrent;
\r
350 this->eglGetCurrentContext = ::eglGetCurrentContext;
\r
351 this->eglGetCurrentSurface = ::eglGetCurrentSurface;
\r
352 this->eglGetCurrentDisplay = ::eglGetCurrentDisplay;
\r
353 this->eglQueryContext = ::eglQueryContext;
\r
354 this->eglWaitGL = ::eglWaitGL;
\r
355 this->eglWaitNative = ::eglWaitNative;
\r
356 this->eglSwapBuffers = ::eglSwapBuffers;
\r
357 this->eglCopyBuffers = ::eglCopyBuffers;
\r
358 this->eglCreateImageKHR = ::eglCreateImageKHR;
\r
359 this->eglDestroyImageKHR = ::eglDestroyImageKHR;
\r
360 this->eglGetProcAddress = ::eglGetProcAddress;
\r
362 this->clientGetCurrentContext = egl::getCurrentContext;
\r
363 this->clientGetCurrentDisplay = egl::getCurrentDisplay;
\r
366 extern "C" LibEGLexports *libEGLexports()
\r
368 static LibEGLexports libEGL;
\r
372 LibGLES_CM libGLES_CM;
\r
373 LibGLESv2 libGLESv2;
\r