Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / main.cpp
1 #include "precompiled.h"
2 //
3 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
6 //
7
8 // main.cpp: DLL entry point and management of thread-local data.
9
10 #include "libGLESv2/main.h"
11 #include "libGLESv2/Context.h"
12
13 #include "common/tls.h"
14
15 static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
16
17 namespace gl
18 {
19
20 Current *AllocateCurrent()
21 {
22     ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
23     if (currentTLS == TLS_OUT_OF_INDEXES)
24     {
25         return NULL;
26     }
27
28     Current *current = new Current();
29     current->context = NULL;
30     current->display = NULL;
31
32     if (!SetTLSValue(currentTLS, current))
33     {
34         ERR("Could not set thread local storage.");
35         return NULL;
36     }
37
38     return current;
39 }
40
41 void DeallocateCurrent()
42 {
43     Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
44     SafeDelete(current);
45     SetTLSValue(currentTLS, NULL);
46 }
47
48 }
49
50 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
51 {
52     switch (reason)
53     {
54       case DLL_PROCESS_ATTACH:
55         {
56             currentTLS = CreateTLSIndex();
57             if (currentTLS == TLS_OUT_OF_INDEXES)
58             {
59                 return FALSE;
60             }
61         }
62         // Fall through to initialize index
63       case DLL_THREAD_ATTACH:
64         {
65             gl::AllocateCurrent();
66         }
67         break;
68       case DLL_THREAD_DETACH:
69         {
70             gl::DeallocateCurrent();
71         }
72         break;
73       case DLL_PROCESS_DETACH:
74         {
75             gl::DeallocateCurrent();
76             DestroyTLSIndex(currentTLS);
77         }
78         break;
79       default:
80         break;
81     }
82
83     return TRUE;
84 }
85
86 namespace gl
87 {
88
89 Current *GetCurrentData()
90 {
91     Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
92
93     // ANGLE issue 488: when the dll is loaded after thread initialization,
94     // thread local storage (current) might not exist yet.
95     return (current ? current : AllocateCurrent());
96 }
97
98 void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
99 {
100     Current *current = GetCurrentData();
101
102     current->context = context;
103     current->display = display;
104
105     if (context && display && surface)
106     {
107         context->makeCurrent(surface);
108     }
109 }
110
111 Context *getContext()
112 {
113     Current *current = GetCurrentData();
114
115     return current->context;
116 }
117
118 Context *getNonLostContext()
119 {
120     Context *context = getContext();
121
122     if (context)
123     {
124         if (context->isContextLost())
125         {
126             gl::error(GL_OUT_OF_MEMORY);
127             return NULL;
128         }
129         else
130         {
131             return context;
132         }
133     }
134     return NULL;
135 }
136
137 egl::Display *getDisplay()
138 {
139     Current *current = GetCurrentData();
140
141     return current->display;
142 }
143
144 // Records an error code
145 void error(GLenum errorCode)
146 {
147     gl::Context *context = glGetCurrentContext();
148
149     if (context)
150     {
151         switch (errorCode)
152         {
153           case GL_INVALID_ENUM:
154             context->recordInvalidEnum();
155             TRACE("\t! Error generated: invalid enum\n");
156             break;
157           case GL_INVALID_VALUE:
158             context->recordInvalidValue();
159             TRACE("\t! Error generated: invalid value\n");
160             break;
161           case GL_INVALID_OPERATION:
162             context->recordInvalidOperation();
163             TRACE("\t! Error generated: invalid operation\n");
164             break;
165           case GL_OUT_OF_MEMORY:
166             context->recordOutOfMemory();
167             TRACE("\t! Error generated: out of memory\n");
168             break;
169           case GL_INVALID_FRAMEBUFFER_OPERATION:
170             context->recordInvalidFramebufferOperation();
171             TRACE("\t! Error generated: invalid framebuffer operation\n");
172             break;
173           default: UNREACHABLE();
174         }
175     }
176 }
177
178 }
179