blob: 4393ae7054c40065a2680c7e6813830d07c309cb [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2012 TransGaming Inc.
4//
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
35 gl::Current *current = new gl::Current;
36
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
50 gl::Current *current = (gl::Current*)sw::Thread::getLocalStorage(currentTLS);
51
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
108namespace gl
109{
110void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
111{
112 Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
113
114 current->context = context;
115 current->display = display;
116
117 if(context && display && surface)
118 {
119 context->makeCurrent(display, surface);
120 }
121}
122
123Context *getContext()
124{
125 Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
126
127 return current->context;
128}
129
130egl::Display *getDisplay()
131{
132 Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
133
134 return current->display;
135}
136
137Device *getDevice()
138{
139 egl::Display *display = getDisplay();
140
141 return display->getDevice();
142}
143}
144
145// Records an error code
146void error(GLenum errorCode)
147{
148 gl::Context *context = gl::getContext();
149
150 if(context)
151 {
152 switch(errorCode)
153 {
154 case GL_INVALID_ENUM:
155 context->recordInvalidEnum();
156 TRACE("\t! Error generated: invalid enum\n");
157 break;
158 case GL_INVALID_VALUE:
159 context->recordInvalidValue();
160 TRACE("\t! Error generated: invalid value\n");
161 break;
162 case GL_INVALID_OPERATION:
163 context->recordInvalidOperation();
164 TRACE("\t! Error generated: invalid operation\n");
165 break;
166 case GL_OUT_OF_MEMORY:
167 context->recordOutOfMemory();
168 TRACE("\t! Error generated: out of memory\n");
169 break;
170 case GL_INVALID_FRAMEBUFFER_OPERATION:
171 context->recordInvalidFramebufferOperation();
172 TRACE("\t! Error generated: invalid framebuffer operation\n");
173 break;
174 default: UNREACHABLE();
175 }
176 }
177}