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
12#include "libGLESv2/Context.h"
13
14static DWORD currentTLS = TLS_OUT_OF_INDEXES;
15
16extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
17{
18    switch (reason)
19    {
20      case DLL_PROCESS_ATTACH:
21        {
22            currentTLS = TlsAlloc();
23
24            if (currentTLS == TLS_OUT_OF_INDEXES)
25            {
26                return FALSE;
27            }
28        }
29        // Fall throught to initialize index
30      case DLL_THREAD_ATTACH:
31        {
32            gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current));
33
34            if (current)
35            {
36                TlsSetValue(currentTLS, current);
37
38                current->context = NULL;
39                current->display = NULL;
40            }
41        }
42        break;
43      case DLL_THREAD_DETACH:
44        {
45            void *current = TlsGetValue(currentTLS);
46
47            if (current)
48            {
49                LocalFree((HLOCAL)current);
50            }
51        }
52        break;
53      case DLL_PROCESS_DETACH:
54        {
55            void *current = TlsGetValue(currentTLS);
56
57            if (current)
58            {
59                LocalFree((HLOCAL)current);
60            }
61
62            TlsFree(currentTLS);
63        }
64        break;
65      default:
66        break;
67    }
68
69    return TRUE;
70}
71
72namespace gl
73{
74void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
75{
76    Current *current = (Current*)TlsGetValue(currentTLS);
77
78    current->context = context;
79    current->display = display;
80
81    if (context && display && surface)
82    {
83        context->makeCurrent(surface);
84    }
85}
86
87Context *getContext()
88{
89    Current *current = (Current*)TlsGetValue(currentTLS);
90
91    return current->context;
92}
93
94Context *getNonLostContext()
95{
96    Context *context = getContext();
97
98    if (context)
99    {
100        if (context->isContextLost())
101        {
102            gl::error(GL_OUT_OF_MEMORY);
103            return NULL;
104        }
105        else
106        {
107            return context;
108        }
109    }
110    return NULL;
111}
112
113egl::Display *getDisplay()
114{
115    Current *current = (Current*)TlsGetValue(currentTLS);
116
117    return current->display;
118}
119
120// Records an error code
121void error(GLenum errorCode)
122{
123    gl::Context *context = glGetCurrentContext();
124
125    if (context)
126    {
127        switch (errorCode)
128        {
129          case GL_INVALID_ENUM:
130            context->recordInvalidEnum();
131            TRACE("\t! Error generated: invalid enum\n");
132            break;
133          case GL_INVALID_VALUE:
134            context->recordInvalidValue();
135            TRACE("\t! Error generated: invalid value\n");
136            break;
137          case GL_INVALID_OPERATION:
138            context->recordInvalidOperation();
139            TRACE("\t! Error generated: invalid operation\n");
140            break;
141          case GL_OUT_OF_MEMORY:
142            context->recordOutOfMemory();
143            TRACE("\t! Error generated: out of memory\n");
144            break;
145          case GL_INVALID_FRAMEBUFFER_OPERATION:
146            context->recordInvalidFramebufferOperation();
147            TRACE("\t! Error generated: invalid framebuffer operation\n");
148            break;
149          default: UNREACHABLE();
150        }
151    }
152}
153
154}
155
156