10bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
20bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens//
30bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Licensed under the Apache License, Version 2.0 (the "License");
40bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// you may not use this file except in compliance with the License.
50bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// You may obtain a copy of the License at
60bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens//
70bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens//    http://www.apache.org/licenses/LICENSE-2.0
80bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens//
90bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Unless required by applicable law or agreed to in writing, software
100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// distributed under the License is distributed on an "AS IS" BASIS,
110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// See the License for the specific language governing permissions and
130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// limitations under the License.
140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// main.cpp: DLL entry point and management of thread-local data.
160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "main.h"
180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "resource.h"
200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Framebuffer.h"
210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Surface.h"
220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "Common/Thread.hpp"
230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "common/debug.h"
240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensstatic sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#if !defined(_MSC_VER)
280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#define CONSTRUCTOR __attribute__((constructor))
290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#define DESTRUCTOR __attribute__((destructor))
300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#else
310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#define CONSTRUCTOR
320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#define DESTRUCTOR
330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#endif
340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensstatic void glAttachThread()
360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	TRACE("()");
380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
3966954c9a014b33fc5fab00a079fd31c22439fe3aNicolas Capens	gl::Current *current = (gl::Current*)sw::Thread::allocateLocalStorage(currentTLS, sizeof(gl::Current));
400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	if(current)
420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	{
430099d70a9ae8521c9fbc7f2eea968ffa4678364aNicolas Capens		current->context = nullptr;
440099d70a9ae8521c9fbc7f2eea968ffa4678364aNicolas Capens		current->display = nullptr;
450099d70a9ae8521c9fbc7f2eea968ffa4678364aNicolas Capens		current->drawSurface = nullptr;
460099d70a9ae8521c9fbc7f2eea968ffa4678364aNicolas Capens		current->readSurface = nullptr;
470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	}
480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensstatic void glDetachThread()
510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	TRACE("()");
530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
540099d70a9ae8521c9fbc7f2eea968ffa4678364aNicolas Capens	wglMakeCurrent(NULL, NULL);
550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
5666954c9a014b33fc5fab00a079fd31c22439fe3aNicolas Capens	sw::Thread::freeLocalStorage(currentTLS);
570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
590bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensCONSTRUCTOR static bool glAttachProcess()
600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	TRACE("()");
620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	#if !(ANGLE_DISABLE_TRACE)
640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		if(debug)
670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		{
680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			fclose(debug);
690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase
700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			fclose(debug);
710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		}
720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	#endif
730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	currentTLS = sw::Thread::allocateLocalStorageKey();
750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	if(currentTLS == TLS_OUT_OF_INDEXES)
770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	{
780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		return false;
790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	}
800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	glAttachThread();
820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	return true;
840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
860bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensDESTRUCTOR static void glDetachProcess()
870bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	TRACE("()");
890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	glDetachThread();
910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	sw::Thread::freeLocalStorageKey(currentTLS);
930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
940bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#if defined(_WIN32)
960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensstatic INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	RECT rect;
990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	switch(uMsg)
1010bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	{
1020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	case WM_INITDIALOG:
1030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		GetWindowRect(GetDesktopWindow(), &rect);
1040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
1050bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		SetTimer(hwnd, 1, 100, NULL);
1060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		return TRUE;
1070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	case WM_COMMAND:
1080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		if(LOWORD(wParam) == IDCANCEL)
1090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		{
1100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			EndDialog(hwnd, 0);
1110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		}
1120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		break;
1130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	case WM_TIMER:
1140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		if(IsDebuggerPresent())
1150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		{
1160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			EndDialog(hwnd, 0);
1170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		}
1180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	}
1190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	return FALSE;
1210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
1220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensstatic void WaitForDebugger(HINSTANCE instance)
1240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
1250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	if(!IsDebuggerPresent())
1260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	{
1270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		HRSRC dialog = FindResource(instance, MAKEINTRESOURCE(IDD_DIALOG1), RT_DIALOG);
1280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		DLGTEMPLATE *dialogTemplate = (DLGTEMPLATE*)LoadResource(instance, dialog);
1290bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		DialogBoxIndirect(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
1300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	}
1310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
1320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensextern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
1340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
1350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	switch(reason)
1360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	{
1370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	case DLL_PROCESS_ATTACH:
1380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		#ifndef NDEBUG
1390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			WaitForDebugger(instance);
1400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		#endif
1410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		return glAttachProcess();
1420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		break;
1430bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	case DLL_THREAD_ATTACH:
1440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		glAttachThread();
1450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		break;
1460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	case DLL_THREAD_DETACH:
1470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		glDetachThread();
1480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		break;
1490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	case DLL_PROCESS_DETACH:
1500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		glDetachProcess();
1510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		break;
1520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	default:
1530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		break;
1540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	}
1550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	return TRUE;
1570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
1580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#endif
1590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensnamespace gl
1610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
1620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensstatic gl::Current *getCurrent(void)
1630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
1640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
1650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	if(!current)
1670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	{
1680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		glAttachThread();
1690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	}
1700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	return (Current*)sw::Thread::getLocalStorage(currentTLS);
1720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
1730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid makeCurrent(Context *context, Display *display, Surface *surface)
1750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
1760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = getCurrent();
1770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	current->context = context;
1790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	current->display = display;
1800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	if(context && display && surface)
1820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	{
1830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		context->makeCurrent(surface);
1840bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	}
1850bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
1860bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1870bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensContext *getContext()
1880bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
1890bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = getCurrent();
1900bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1910bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	return current->context;
1920bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
1930bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1940bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensDisplay *getDisplay()
1950bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
1960bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = getCurrent();
1970bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
1980bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	return current->display;
1990bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
2000bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2010bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensDevice *getDevice()
2020bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
2030bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Context *context = getContext();
2040bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2050099d70a9ae8521c9fbc7f2eea968ffa4678364aNicolas Capens	return context ? context->getDevice() : nullptr;
2060bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
2070bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2080bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid setCurrentDisplay(Display *dpy)
2090bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
2100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = getCurrent();
2110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	current->display = dpy;
2130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
2140bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2150bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid setCurrentContext(gl::Context *ctx)
2160bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
2170bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = getCurrent();
2180bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2190bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	current->context = ctx;
2200bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
2210bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2220bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid setCurrentDrawSurface(Surface *surface)
2230bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
2240bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = getCurrent();
2250bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2260bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	current->drawSurface = surface;
2270bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
2280bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2290bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensSurface *getCurrentDrawSurface()
2300bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
2310bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = getCurrent();
2320bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2330bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	return current->drawSurface;
2340bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
2350bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2360bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid setCurrentReadSurface(Surface *surface)
2370bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
2380bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = getCurrent();
2390bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2400bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	current->readSurface = surface;
2410bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
2420bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2430bac285a78df6a6d7a6b68784748b92805420ffbNicolas CapensSurface *getCurrentReadSurface()
2440bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
2450bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	Current *current = getCurrent();
2460bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2470bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	return current->readSurface;
2480bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
2490bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
2500bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2510bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens// Records an error code
2520bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capensvoid error(GLenum errorCode)
2530bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens{
2540bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	gl::Context *context = gl::getContext();
2550bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
2560bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	if(context)
2570bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	{
2580bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		switch(errorCode)
2590bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		{
2600bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		case GL_INVALID_ENUM:
2610bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			context->recordInvalidEnum();
2620bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			TRACE("\t! Error generated: invalid enum\n");
2630bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			break;
2640bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		case GL_INVALID_VALUE:
2650bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			context->recordInvalidValue();
2660bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			TRACE("\t! Error generated: invalid value\n");
2670bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			break;
2680bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		case GL_INVALID_OPERATION:
2690bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			context->recordInvalidOperation();
2700bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			TRACE("\t! Error generated: invalid operation\n");
2710bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			break;
2720bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		case GL_OUT_OF_MEMORY:
2730bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			context->recordOutOfMemory();
2740bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			TRACE("\t! Error generated: out of memory\n");
2750bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			break;
2760bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		case GL_INVALID_FRAMEBUFFER_OPERATION:
2770bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			context->recordInvalidFramebufferOperation();
2780bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			TRACE("\t! Error generated: invalid framebuffer operation\n");
2790bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens			break;
2800bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		default: UNREACHABLE(errorCode);
2810bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens		}
2820bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens	}
2830bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens}
284