• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // main.cpp: DLL entry point and management of thread-local data.
16 
17 #include "main.h"
18 
19 #include "resource.h"
20 #include "Framebuffer.h"
21 #include "Surface.h"
22 #include "Common/Thread.hpp"
23 #include "common/debug.h"
24 
25 static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
26 
27 #if !defined(_MSC_VER)
28 #define CONSTRUCTOR __attribute__((constructor))
29 #define DESTRUCTOR __attribute__((destructor))
30 #else
31 #define CONSTRUCTOR
32 #define DESTRUCTOR
33 #endif
34 
glAttachThread()35 static void glAttachThread()
36 {
37 	TRACE("()");
38 
39 	gl::Current *current = new gl::Current;
40 
41 	if(current)
42 	{
43 		sw::Thread::setLocalStorage(currentTLS, current);
44 
45 		current->context = 0;
46 		current->display = 0;
47 		current->drawSurface = 0;
48 		current->readSurface = 0;
49 	}
50 }
51 
glDetachThread()52 static void glDetachThread()
53 {
54 	TRACE("()");
55 
56 	gl::Current *current = (gl::Current*)sw::Thread::getLocalStorage(currentTLS);
57 
58 	if(current)
59 	{
60 		delete current;
61 	}
62 }
63 
glAttachProcess()64 CONSTRUCTOR static bool glAttachProcess()
65 {
66 	TRACE("()");
67 
68 	#if !(ANGLE_DISABLE_TRACE)
69 		FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
70 
71 		if(debug)
72 		{
73 			fclose(debug);
74 			debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase
75 			fclose(debug);
76 		}
77 	#endif
78 
79 	currentTLS = sw::Thread::allocateLocalStorageKey();
80 
81 	if(currentTLS == TLS_OUT_OF_INDEXES)
82 	{
83 		return false;
84 	}
85 
86 	glAttachThread();
87 
88 	return true;
89 }
90 
glDetachProcess()91 DESTRUCTOR static void glDetachProcess()
92 {
93 	TRACE("()");
94 
95 	glDetachThread();
96 
97 	sw::Thread::freeLocalStorageKey(currentTLS);
98 }
99 
100 #if defined(_WIN32)
DebuggerWaitDialogProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)101 static INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
102 {
103 	RECT rect;
104 
105 	switch(uMsg)
106 	{
107 	case WM_INITDIALOG:
108 		GetWindowRect(GetDesktopWindow(), &rect);
109 		SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
110 		SetTimer(hwnd, 1, 100, NULL);
111 		return TRUE;
112 	case WM_COMMAND:
113 		if(LOWORD(wParam) == IDCANCEL)
114 		{
115 			EndDialog(hwnd, 0);
116 		}
117 		break;
118 	case WM_TIMER:
119 		if(IsDebuggerPresent())
120 		{
121 			EndDialog(hwnd, 0);
122 		}
123 	}
124 
125 	return FALSE;
126 }
127 
WaitForDebugger(HINSTANCE instance)128 static void WaitForDebugger(HINSTANCE instance)
129 {
130 	if(!IsDebuggerPresent())
131 	{
132 		HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
133 		DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);
134 		DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
135 	}
136 }
137 
DllMain(HINSTANCE instance,DWORD reason,LPVOID reserved)138 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
139 {
140 	switch(reason)
141 	{
142 	case DLL_PROCESS_ATTACH:
143 		#ifndef NDEBUG
144 			WaitForDebugger(instance);
145 		#endif
146 		return glAttachProcess();
147 		break;
148 	case DLL_THREAD_ATTACH:
149 		glAttachThread();
150 		break;
151 	case DLL_THREAD_DETACH:
152 		glDetachThread();
153 		break;
154 	case DLL_PROCESS_DETACH:
155 		glDetachProcess();
156 		break;
157 	default:
158 		break;
159 	}
160 
161 	return TRUE;
162 }
163 #endif
164 
165 namespace gl
166 {
getCurrent(void)167 static gl::Current *getCurrent(void)
168 {
169 	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
170 
171 	if(!current)
172 	{
173 		glAttachThread();
174 	}
175 
176 	return (Current*)sw::Thread::getLocalStorage(currentTLS);
177 }
178 
makeCurrent(Context * context,Display * display,Surface * surface)179 void makeCurrent(Context *context, Display *display, Surface *surface)
180 {
181 	Current *current = getCurrent();
182 
183 	current->context = context;
184 	current->display = display;
185 
186 	if(context && display && surface)
187 	{
188 		context->makeCurrent(surface);
189 	}
190 }
191 
getContext()192 Context *getContext()
193 {
194 	Current *current = getCurrent();
195 
196 	return current->context;
197 }
198 
getDisplay()199 Display *getDisplay()
200 {
201 	Current *current = getCurrent();
202 
203 	return current->display;
204 }
205 
getDevice()206 Device *getDevice()
207 {
208 	Context *context = getContext();
209 
210 	return context ? context->getDevice() : 0;
211 }
212 
setCurrentDisplay(Display * dpy)213 void setCurrentDisplay(Display *dpy)
214 {
215 	Current *current = getCurrent();
216 
217 	current->display = dpy;
218 }
219 
setCurrentContext(gl::Context * ctx)220 void setCurrentContext(gl::Context *ctx)
221 {
222 	Current *current = getCurrent();
223 
224 	current->context = ctx;
225 }
226 
setCurrentDrawSurface(Surface * surface)227 void setCurrentDrawSurface(Surface *surface)
228 {
229 	Current *current = getCurrent();
230 
231 	current->drawSurface = surface;
232 }
233 
getCurrentDrawSurface()234 Surface *getCurrentDrawSurface()
235 {
236 	Current *current = getCurrent();
237 
238 	return current->drawSurface;
239 }
240 
setCurrentReadSurface(Surface * surface)241 void setCurrentReadSurface(Surface *surface)
242 {
243 	Current *current = getCurrent();
244 
245 	current->readSurface = surface;
246 }
247 
getCurrentReadSurface()248 Surface *getCurrentReadSurface()
249 {
250 	Current *current = getCurrent();
251 
252 	return current->readSurface;
253 }
254 }
255 
256 // Records an error code
error(GLenum errorCode)257 void error(GLenum errorCode)
258 {
259 	gl::Context *context = gl::getContext();
260 
261 	if(context)
262 	{
263 		switch(errorCode)
264 		{
265 		case GL_INVALID_ENUM:
266 			context->recordInvalidEnum();
267 			TRACE("\t! Error generated: invalid enum\n");
268 			break;
269 		case GL_INVALID_VALUE:
270 			context->recordInvalidValue();
271 			TRACE("\t! Error generated: invalid value\n");
272 			break;
273 		case GL_INVALID_OPERATION:
274 			context->recordInvalidOperation();
275 			TRACE("\t! Error generated: invalid operation\n");
276 			break;
277 		case GL_OUT_OF_MEMORY:
278 			context->recordOutOfMemory();
279 			TRACE("\t! Error generated: out of memory\n");
280 			break;
281 		case GL_INVALID_FRAMEBUFFER_OPERATION:
282 			context->recordInvalidFramebufferOperation();
283 			TRACE("\t! Error generated: invalid framebuffer operation\n");
284 			break;
285 		default: UNREACHABLE(errorCode);
286 		}
287 	}
288 }
289