blob: 43f8e3803695a963adf42d4848b13713bc9055d7 [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"
19#include "common/debug.h"
20
21static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
22
23#if !defined(_MSC_VER)
24#define CONSTRUCTOR __attribute__((constructor))
25#define DESTRUCTOR __attribute__((destructor))
26#else
27#define CONSTRUCTOR
28#define DESTRUCTOR
29#endif
30
31static void glAttachThread()
32{
33 TRACE("()");
34
Nicolas Capensf9b76a82014-10-28 01:55:27 -040035 gl2::Current *current = new gl2::Current;
John Bauman66b8ab22014-05-06 15:57:45 -040036
37 if(current)
38 {
39 sw::Thread::setLocalStorage(currentTLS, current);
40
41 current->context = NULL;
42 current->display = NULL;
43 }
44}
45
46static void glDetachThread()
47{
48 TRACE("()");
49
Nicolas Capensf9b76a82014-10-28 01:55:27 -040050 gl2::Current *current = (gl2::Current*)sw::Thread::getLocalStorage(currentTLS);
John Bauman66b8ab22014-05-06 15:57:45 -040051
52 if(current)
53 {
54 delete current;
55 }
56}
57
58CONSTRUCTOR static bool glAttachProcess()
59{
60 TRACE("()");
61
62 currentTLS = sw::Thread::allocateLocalStorageKey();
63
64 if(currentTLS == TLS_OUT_OF_INDEXES)
65 {
66 return false;
67 }
68
69 glAttachThread();
70
71 return true;
72}
73
74DESTRUCTOR static void glDetachProcess()
75{
76 TRACE("()");
77
78 glDetachThread();
79
80 sw::Thread::freeLocalStorageKey(currentTLS);
81}
82
83#if defined(_WIN32)
84extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
85{
86 switch(reason)
87 {
88 case DLL_PROCESS_ATTACH:
89 return glAttachProcess();
90 break;
91 case DLL_THREAD_ATTACH:
92 glAttachThread();
93 break;
94 case DLL_THREAD_DETACH:
95 glDetachThread();
96 break;
97 case DLL_PROCESS_DETACH:
98 glDetachProcess();
99 break;
100 default:
101 break;
102 }
103
104 return TRUE;
105}
106#endif
107
Nicolas Capensf9b76a82014-10-28 01:55:27 -0400108namespace gl2
John Bauman66b8ab22014-05-06 15:57:45 -0400109{
Nicolas Capensf9b76a82014-10-28 01:55:27 -0400110static gl2::Current *getCurrent(void)
John Baumand4ae8632014-05-06 16:18:33 -0400111{
112 Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
113
114 if(!current)
115 {
116 glAttachThread();
117 }
118
119 return (Current*)sw::Thread::getLocalStorage(currentTLS);
120}
121
John Bauman66b8ab22014-05-06 15:57:45 -0400122void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
123{
John Baumand4ae8632014-05-06 16:18:33 -0400124 Current *current = getCurrent();
John Bauman66b8ab22014-05-06 15:57:45 -0400125
126 current->context = context;
127 current->display = display;
128
129 if(context && display && surface)
130 {
131 context->makeCurrent(display, surface);
132 }
133}
134
135Context *getContext()
136{
John Baumand4ae8632014-05-06 16:18:33 -0400137 Current *current = getCurrent();
John Bauman66b8ab22014-05-06 15:57:45 -0400138
139 return current->context;
140}
141
142egl::Display *getDisplay()
143{
John Baumand4ae8632014-05-06 16:18:33 -0400144 Current *current = getCurrent();
John Bauman66b8ab22014-05-06 15:57:45 -0400145
146 return current->display;
147}
148
149Device *getDevice()
150{
Nicolas Capensc78445c2014-10-27 17:29:04 -0400151 Context *context = getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400152
Nicolas Capensc78445c2014-10-27 17:29:04 -0400153 return context ? context->getDevice() : 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400154}
155}
156
157// Records an error code
158void error(GLenum errorCode)
159{
Nicolas Capensf9b76a82014-10-28 01:55:27 -0400160 gl2::Context *context = gl2::getContext();
John Bauman66b8ab22014-05-06 15:57:45 -0400161
162 if(context)
163 {
164 switch(errorCode)
165 {
166 case GL_INVALID_ENUM:
167 context->recordInvalidEnum();
168 TRACE("\t! Error generated: invalid enum\n");
169 break;
170 case GL_INVALID_VALUE:
171 context->recordInvalidValue();
172 TRACE("\t! Error generated: invalid value\n");
173 break;
174 case GL_INVALID_OPERATION:
175 context->recordInvalidOperation();
176 TRACE("\t! Error generated: invalid operation\n");
177 break;
178 case GL_OUT_OF_MEMORY:
179 context->recordOutOfMemory();
180 TRACE("\t! Error generated: out of memory\n");
181 break;
182 case GL_INVALID_FRAMEBUFFER_OPERATION:
183 context->recordInvalidFramebufferOperation();
184 TRACE("\t! Error generated: invalid framebuffer operation\n");
185 break;
186 default: UNREACHABLE();
187 }
188 }
189}