blob: 6055850f5b974f792cd733627a2a8a5047163aad [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 Capensafd1f9f2014-10-28 02:53:50 -040046 #if defined(_WIN32)
47 const char *libEGL_lib = "libEGL.dll";
48 #else
49 const char *libEGL_lib = "libEGL.so.1";
50 #endif
51
52 libEGL = loadLibrary(libEGL_lib);
53 egl::getCurrentContext = (egl::Context *(*)())getProcAddress(libEGL, "eglGetCurrentContext");
54 egl::getCurrentDisplay = (egl::Display *(*)())getProcAddress(libEGL, "eglGetCurrentDisplay");
55
Nicolas Capensd76b5df2014-10-28 15:54:46 -040056 #if defined(_WIN32)
57 const char *libGLES_CM_lib = "libGLES_CM.dll";
58 #else
59 const char *libGLES_CM_lib = "libGLES_CM.so.1";
60 #endif
61
62 libGLES_CM = loadLibrary(libGLES_CM_lib);
63 gl::getProcAddress = (__eglMustCastToProperFunctionPointerType (*)(const char*))getProcAddress(libGLES_CM, "glGetProcAddress");
64
Nicolas Capensafd1f9f2014-10-28 02:53:50 -040065 return libEGL != 0;
John Bauman66b8ab22014-05-06 15:57:45 -040066}
67
68DESTRUCTOR static void glDetachProcess()
69{
70 TRACE("()");
71
72 glDetachThread();
Nicolas Capensafd1f9f2014-10-28 02:53:50 -040073 freeLibrary(libEGL);
Nicolas Capensd76b5df2014-10-28 15:54:46 -040074 freeLibrary(libGLES_CM);
John Bauman66b8ab22014-05-06 15:57:45 -040075}
76
77#if defined(_WIN32)
78extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
79{
80 switch(reason)
81 {
82 case DLL_PROCESS_ATTACH:
83 return glAttachProcess();
84 break;
85 case DLL_THREAD_ATTACH:
86 glAttachThread();
87 break;
88 case DLL_THREAD_DETACH:
89 glDetachThread();
90 break;
91 case DLL_PROCESS_DETACH:
92 glDetachProcess();
93 break;
94 default:
95 break;
96 }
97
98 return TRUE;
99}
100#endif
101
Nicolas Capensf9b76a82014-10-28 01:55:27 -0400102namespace gl2
John Bauman66b8ab22014-05-06 15:57:45 -0400103{
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400104gl2::Context *getContext()
John Baumand4ae8632014-05-06 16:18:33 -0400105{
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400106 egl::Context *context = egl::getCurrentContext();
107
108 if(context && context->getClientVersion() == 2)
John Baumand4ae8632014-05-06 16:18:33 -0400109 {
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400110 return static_cast<gl2::Context*>(context);
John Baumand4ae8632014-05-06 16:18:33 -0400111 }
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400112
113 return 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400114}
115
116egl::Display *getDisplay()
117{
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400118 return egl::getCurrentDisplay();
John Bauman66b8ab22014-05-06 15:57:45 -0400119}
120
121Device *getDevice()
122{
Nicolas Capensc78445c2014-10-27 17:29:04 -0400123 Context *context = getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400124
Nicolas Capensc78445c2014-10-27 17:29:04 -0400125 return context ? context->getDevice() : 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400126}
127}
128
Nicolas Capensd76b5df2014-10-28 15:54:46 -0400129namespace egl
130{
131GLint getClientVersion()
132{
133 Context *context = egl::getCurrentContext();
134
135 return context ? context->getClientVersion() : 0;
136}
137}
138
John Bauman66b8ab22014-05-06 15:57:45 -0400139// Records an error code
140void error(GLenum errorCode)
141{
Nicolas Capensf9b76a82014-10-28 01:55:27 -0400142 gl2::Context *context = gl2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400143
144 if(context)
145 {
146 switch(errorCode)
147 {
148 case GL_INVALID_ENUM:
149 context->recordInvalidEnum();
150 TRACE("\t! Error generated: invalid enum\n");
151 break;
152 case GL_INVALID_VALUE:
153 context->recordInvalidValue();
154 TRACE("\t! Error generated: invalid value\n");
155 break;
156 case GL_INVALID_OPERATION:
157 context->recordInvalidOperation();
158 TRACE("\t! Error generated: invalid operation\n");
159 break;
160 case GL_OUT_OF_MEMORY:
161 context->recordOutOfMemory();
162 TRACE("\t! Error generated: out of memory\n");
163 break;
164 case GL_INVALID_FRAMEBUFFER_OPERATION:
165 context->recordInvalidFramebufferOperation();
166 TRACE("\t! Error generated: invalid framebuffer operation\n");
167 break;
168 default: UNREACHABLE();
169 }
170 }
171}
Nicolas Capensafd1f9f2014-10-28 02:53:50 -0400172
173namespace egl
174{
175 egl::Context *(*getCurrentContext)() = 0;
176 egl::Display *(*getCurrentDisplay)() = 0;
177}
178
Nicolas Capensd76b5df2014-10-28 15:54:46 -0400179namespace gl
180{
181 __eglMustCastToProperFunctionPointerType (*getProcAddress)(const char *procname) = 0;
182}
183
184void *libEGL = 0; // Handle to the libEGL module
185void *libGLES_CM = 0; // Handle to the libGLES_CM module