blob: f185beeb398f1f378ae1da4a23a541cdac7751e0 [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001// SwiftShader Software Renderer
2//
John Baumand4ae8632014-05-06 16:18:33 -04003// Copyright(c) 2005-2013 TransGaming Inc.
John Bauman66b8ab22014-05-06 15:57:45 -04004//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12// main.cpp: DLL entry point and management of thread-local data.
13
14#include "main.h"
15
16#include "Framebuffer.h"
17#include "libEGL/Surface.h"
18#include "Common/Thread.hpp"
Nicolas Capensafd1f9f2014-10-28 02:53:50 -040019#include "Common/SharedLibrary.hpp"
John Bauman66b8ab22014-05-06 15:57:45 -040020#include "common/debug.h"
21
John Bauman66b8ab22014-05-06 15:57:45 -040022#if !defined(_MSC_VER)
23#define CONSTRUCTOR __attribute__((constructor))
24#define DESTRUCTOR __attribute__((destructor))
25#else
26#define CONSTRUCTOR
27#define DESTRUCTOR
28#endif
29
30static void glAttachThread()
31{
32 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -040033}
34
35static void glDetachThread()
36{
37 TRACE("()");
John Bauman66b8ab22014-05-06 15:57:45 -040038}
39
40CONSTRUCTOR static bool glAttachProcess()
41{
42 TRACE("()");
43
John Bauman66b8ab22014-05-06 15:57:45 -040044 glAttachThread();
45
Nicolas Capense2540102014-11-05 09:34:52 -050046 #if defined(_WIN32)
47 const char *libEGL_lib[] = {"libEGL.dll", "libEGL_translator.dll"};
Greg Hartman9a10e062015-03-20 13:29:14 -070048 #elif defined(__ANDROID__)
Greg Hartman36e22de2015-03-31 16:01:46 -070049 const char *libEGL_lib[] = {"/vendor/lib/egl/libEGL_swiftshader.so"};
Nicolas Capens4cadfe32014-12-10 22:26:26 -050050 #elif defined(__LP64__)
51 const char *libEGL_lib[] = {"lib64EGL_translator.so", "libEGL.so.1", "libEGL.so"};
Nicolas Capensafd1f9f2014-10-28 02:53:50 -040052 #else
Nicolas Capens8d869e02014-12-08 16:52:06 -050053 const char *libEGL_lib[] = {"libEGL_translator.so", "libEGL.so.1", "libEGL.so"};
Nicolas Capensafd1f9f2014-10-28 02:53:50 -040054 #endif
55
56 libEGL = loadLibrary(libEGL_lib);
Nicolas Capens53e38862014-11-05 16:05:12 -050057 egl::getCurrentContext = (egl::Context *(*)())getProcAddress(libEGL, "clientGetCurrentContext");
58 egl::getCurrentDisplay = (egl::Display *(*)())getProcAddress(libEGL, "clientGetCurrentDisplay");
Nicolas Capensafd1f9f2014-10-28 02:53:50 -040059
Nicolas Capensd76b5df2014-10-28 15:54:46 -040060 #if defined(_WIN32)
Nicolas Capense2540102014-11-05 09:34:52 -050061 const char *libGLES_CM_lib[] = {"libGLES_CM.dll", "libGLES_CM_translator.dll"};
Greg Hartman9a10e062015-03-20 13:29:14 -070062 #elif defined(__ANDROID__)
Greg Hartman36e22de2015-03-31 16:01:46 -070063 const char *libGLES_CM_lib[] = {"/vendor/lib/egl/libGLESv1_CM_swiftshader.so"};
Nicolas Capens4cadfe32014-12-10 22:26:26 -050064 #elif defined(__LP64__)
65 const char *libGLES_CM_lib[] = {"lib64GLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
Nicolas Capensd76b5df2014-10-28 15:54:46 -040066 #else
Nicolas Capens8d869e02014-12-08 16:52:06 -050067 const char *libGLES_CM_lib[] = {"libGLES_CM_translator.so", "libGLES_CM.so.1", "libGLES_CM.so"};
Nicolas Capensd76b5df2014-10-28 15:54:46 -040068 #endif
69
70 libGLES_CM = loadLibrary(libGLES_CM_lib);
Nicolas Capens14ee7622014-10-28 23:48:41 -040071 es1::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLES_CM, "glGetProcAddress");
Nicolas Capensd76b5df2014-10-28 15:54:46 -040072
Nicolas Capensafd1f9f2014-10-28 02:53:50 -040073 return libEGL != 0;
John Bauman66b8ab22014-05-06 15:57:45 -040074}
75
76DESTRUCTOR static void glDetachProcess()
77{
78 TRACE("()");
79
80 glDetachThread();
Nicolas Capensafd1f9f2014-10-28 02:53:50 -040081 freeLibrary(libEGL);
Nicolas Capensd76b5df2014-10-28 15:54:46 -040082 freeLibrary(libGLES_CM);
John Bauman66b8ab22014-05-06 15:57:45 -040083}
84
85#if defined(_WIN32)
86extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
87{
88 switch(reason)
89 {
90 case DLL_PROCESS_ATTACH:
91 return glAttachProcess();
92 break;
93 case DLL_THREAD_ATTACH:
94 glAttachThread();
95 break;
96 case DLL_THREAD_DETACH:
97 glDetachThread();
98 break;
99 case DLL_PROCESS_DETACH:
100 glDetachProcess();
101 break;
102 default:
103 break;
104 }
105
106 return TRUE;
107}
108#endif
109
Nicolas Capens14ee7622014-10-28 23:48:41 -0400110namespace es2
John Bauman66b8ab22014-05-06 15:57:45 -0400111{
Nicolas Capens14ee7622014-10-28 23:48:41 -0400112es2::Context *getContext()
John Baumand4ae8632014-05-06 16:18:33 -0400113{
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400114 egl::Context *context = egl::getCurrentContext();
Nicolas Capens8d869e02014-12-08 16:52:06 -0500115
Nicolas Capensb97ad2e2015-02-11 17:40:30 -0500116 if(context && (context->getClientVersion() == 2 ||
117 context->getClientVersion() == 3))
John Baumand4ae8632014-05-06 16:18:33 -0400118 {
Nicolas Capens14ee7622014-10-28 23:48:41 -0400119 return static_cast<es2::Context*>(context);
John Baumand4ae8632014-05-06 16:18:33 -0400120 }
Nicolas Capens8d869e02014-12-08 16:52:06 -0500121
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400122 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400123}
124
125egl::Display *getDisplay()
126{
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400127 return egl::getCurrentDisplay();
John Bauman66b8ab22014-05-06 15:57:45 -0400128}
129
130Device *getDevice()
131{
Nicolas Capensc78445c2014-10-27 17:29:04 -0400132 Context *context = getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400133
Nicolas Capensc78445c2014-10-27 17:29:04 -0400134 return context ? context->getDevice() : 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400135}
136}
137
Nicolas Capensd76b5df2014-10-28 15:54:46 -0400138namespace egl
139{
140GLint getClientVersion()
141{
142 Context *context = egl::getCurrentContext();
143
144 return context ? context->getClientVersion() : 0;
145}
146}
147
John Bauman66b8ab22014-05-06 15:57:45 -0400148// Records an error code
149void error(GLenum errorCode)
150{
Nicolas Capens14ee7622014-10-28 23:48:41 -0400151 es2::Context *context = es2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400152
153 if(context)
154 {
155 switch(errorCode)
156 {
157 case GL_INVALID_ENUM:
158 context->recordInvalidEnum();
159 TRACE("\t! Error generated: invalid enum\n");
160 break;
161 case GL_INVALID_VALUE:
162 context->recordInvalidValue();
163 TRACE("\t! Error generated: invalid value\n");
164 break;
165 case GL_INVALID_OPERATION:
166 context->recordInvalidOperation();
167 TRACE("\t! Error generated: invalid operation\n");
168 break;
169 case GL_OUT_OF_MEMORY:
170 context->recordOutOfMemory();
171 TRACE("\t! Error generated: out of memory\n");
172 break;
173 case GL_INVALID_FRAMEBUFFER_OPERATION:
174 context->recordInvalidFramebufferOperation();
175 TRACE("\t! Error generated: invalid framebuffer operation\n");
176 break;
177 default: UNREACHABLE();
178 }
179 }
180}
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400181
182namespace egl
183{
184 egl::Context *(*getCurrentContext)() = 0;
185 egl::Display *(*getCurrentDisplay)() = 0;
186}
187
Nicolas Capens14ee7622014-10-28 23:48:41 -0400188namespace es1
Nicolas Capensd76b5df2014-10-28 15:54:46 -0400189{
190 __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;
191}
192
193void *libEGL = 0; // Handle to the libEGL module
194void *libGLES_CM = 0; // Handle to the libGLES_CM module