Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / main.cpp
1 //
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.
5 //
6
7 // main.cpp: DLL entry point and management of thread-local data.
8
9 #include "libGLESv2/main.h"
10 #include "libGLESv2/Context.h"
11
12 #include "common/tls.h"
13
14 static TLSIndex currentTLS = TLS_INVALID_INDEX;
15
16 namespace gl
17 {
18
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.
26
27 // Call this exactly once at process startup.
28 bool CreateThreadLocalIndex()
29 {
30     currentTLS = CreateTLSIndex();
31     if (currentTLS == TLS_INVALID_INDEX)
32     {
33         return false;
34     }
35     return true;
36 }
37
38 // Call this exactly once at process shutdown.
39 void DestroyThreadLocalIndex()
40 {
41     DestroyTLSIndex(currentTLS);
42     currentTLS = TLS_INVALID_INDEX;
43 }
44
45 // Call this upon thread startup.
46 Current *AllocateCurrent()
47 {
48     ASSERT(currentTLS != TLS_INVALID_INDEX);
49     if (currentTLS == TLS_INVALID_INDEX)
50     {
51         return NULL;
52     }
53
54     Current *current = new Current();
55     current->context = NULL;
56     current->display = NULL;
57
58     if (!SetTLSValue(currentTLS, current))
59     {
60         ERR("Could not set thread local storage.");
61         return NULL;
62     }
63
64     return current;
65 }
66
67 // Call this upon thread shutdown.
68 void DeallocateCurrent()
69 {
70     Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
71     SafeDelete(current);
72     SetTLSValue(currentTLS, NULL);
73 }
74
75 }
76
77 #ifdef ANGLE_PLATFORM_WINDOWS
78 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
79 {
80     switch (reason)
81     {
82       case DLL_PROCESS_ATTACH:
83         {
84             if (!gl::CreateThreadLocalIndex())
85             {
86                 return FALSE;
87             }
88
89 #ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
90             gl::InitializeDebugAnnotations();
91 #endif
92         }
93         // Fall through to initialize index
94       case DLL_THREAD_ATTACH:
95         {
96             gl::AllocateCurrent();
97         }
98         break;
99       case DLL_THREAD_DETACH:
100         {
101             gl::DeallocateCurrent();
102         }
103         break;
104       case DLL_PROCESS_DETACH:
105         {
106             gl::DeallocateCurrent();
107             gl::DestroyThreadLocalIndex();
108
109 #ifdef ANGLE_ENABLE_DEBUG_ANNOTATIONS
110             gl::UninitializeDebugAnnotations();
111 #endif
112         }
113         break;
114       default:
115         break;
116     }
117
118     return TRUE;
119 }
120 #endif
121
122 namespace gl
123 {
124
125 Current *GetCurrentData()
126 {
127     Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
128
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());
132 }
133
134 void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
135 {
136     Current *current = GetCurrentData();
137
138     current->context = context;
139     current->display = display;
140
141     if (context && display && surface)
142     {
143         context->makeCurrent(surface);
144     }
145 }
146
147 Context *getContext()
148 {
149     Current *current = GetCurrentData();
150
151     return current->context;
152 }
153
154 Context *getNonLostContext()
155 {
156     Context *context = getContext();
157
158     if (context)
159     {
160         if (context->isContextLost())
161         {
162             gl::error(GL_OUT_OF_MEMORY);
163             return NULL;
164         }
165         else
166         {
167             return context;
168         }
169     }
170     return NULL;
171 }
172
173 egl::Display *getDisplay()
174 {
175     Current *current = GetCurrentData();
176
177     return current->display;
178 }
179
180 // Records an error code
181 void error(GLenum errorCode)
182 {
183     gl::Context *context = glGetCurrentContext();
184     context->recordError(Error(errorCode));
185
186     switch (errorCode)
187     {
188       case GL_INVALID_ENUM:
189         TRACE("\t! Error generated: invalid enum\n");
190         break;
191       case GL_INVALID_VALUE:
192         TRACE("\t! Error generated: invalid value\n");
193         break;
194       case GL_INVALID_OPERATION:
195         TRACE("\t! Error generated: invalid operation\n");
196         break;
197       case GL_OUT_OF_MEMORY:
198         TRACE("\t! Error generated: out of memory\n");
199         break;
200       case GL_INVALID_FRAMEBUFFER_OPERATION:
201         TRACE("\t! Error generated: invalid framebuffer operation\n");
202         break;
203       default: UNREACHABLE();
204     }
205 }
206
207 }