2 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
7 // main.cpp: DLL entry point and management of thread-local data.
9 #include "libGLESv2/main.h"
10 #include "libGLESv2/Context.h"
12 #include "common/tls.h"
14 static TLSIndex currentTLS = TLS_INVALID_INDEX;
19 // TODO(kbr): figure out how these are going to be managed on
20 // non-Windows platforms. These routines would need to be exported
21 // from ANGLE and called cooperatively when users create and destroy
22 // threads -- or the initialization of the TLS index, and allocation
23 // of thread-local data, will have to be done lazily. Will have to use
24 // destructor function with pthread_create_key on POSIX platforms to
25 // clean up thread-local data.
27 // Call this exactly once at process startup.
28 bool CreateThreadLocalIndex()
30 currentTLS = CreateTLSIndex();
31 if (currentTLS == TLS_INVALID_INDEX)
38 // Call this exactly once at process shutdown.
39 void DestroyThreadLocalIndex()
41 DestroyTLSIndex(currentTLS);
42 currentTLS = TLS_INVALID_INDEX;
45 // Call this upon thread startup.
46 Current *AllocateCurrent()
48 ASSERT(currentTLS != TLS_INVALID_INDEX);
49 if (currentTLS == TLS_INVALID_INDEX)
54 Current *current = new Current();
55 current->context = NULL;
56 current->display = NULL;
58 if (!SetTLSValue(currentTLS, current))
60 ERR("Could not set thread local storage.");
67 // Call this upon thread shutdown.
68 void DeallocateCurrent()
70 Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
72 SetTLSValue(currentTLS, NULL);
77 #ifdef ANGLE_PLATFORM_WINDOWS
78 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
82 case DLL_PROCESS_ATTACH:
84 if (!gl::CreateThreadLocalIndex())
89 #ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
90 gl::InitializeDebugAnnotations();
93 // Fall through to initialize index
94 case DLL_THREAD_ATTACH:
96 gl::AllocateCurrent();
99 case DLL_THREAD_DETACH:
101 gl::DeallocateCurrent();
104 case DLL_PROCESS_DETACH:
106 gl::DeallocateCurrent();
107 gl::DestroyThreadLocalIndex();
109 #ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
110 gl::UninitializeDebugAnnotations();
125 Current *GetCurrentData()
127 Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
129 // ANGLE issue 488: when the dll is loaded after thread initialization,
130 // thread local storage (current) might not exist yet.
131 return (current ? current : AllocateCurrent());
134 void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
136 Current *current = GetCurrentData();
138 current->context = context;
139 current->display = display;
141 if (context && display && surface)
143 context->makeCurrent(surface);
147 Context *getContext()
149 Current *current = GetCurrentData();
151 return current->context;
154 Context *getNonLostContext()
156 Context *context = getContext();
160 if (context->isContextLost())
162 gl::error(GL_OUT_OF_MEMORY);
173 egl::Display *getDisplay()
175 Current *current = GetCurrentData();
177 return current->display;
180 // Records an error code
181 void error(GLenum errorCode)
183 gl::Context *context = glGetCurrentContext();
184 context->recordError(Error(errorCode));
188 case GL_INVALID_ENUM:
189 TRACE("\t! Error generated: invalid enum\n");
191 case GL_INVALID_VALUE:
192 TRACE("\t! Error generated: invalid value\n");
194 case GL_INVALID_OPERATION:
195 TRACE("\t! Error generated: invalid operation\n");
197 case GL_OUT_OF_MEMORY:
198 TRACE("\t! Error generated: out of memory\n");
200 case GL_INVALID_FRAMEBUFFER_OPERATION:
201 TRACE("\t! Error generated: invalid framebuffer operation\n");
203 default: UNREACHABLE();