blob: 0a69d411aa3f58430a325d976ed1213f7c9f6b12 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
daniel@transgaming.comfad16ed2012-10-17 18:24:01 +00002// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// 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
daniel@transgaming.combbf56f72010-04-20 18:52:13 +00009#include "libGLESv2/main.h"
daniel@transgaming.com78d44862011-11-09 17:46:33 +000010#include "libGLESv2/utilities.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000011
alokp@chromium.orgea0e1af2010-03-22 19:33:14 +000012#include "common/debug.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000013#include "libEGL/Surface.h"
14
15#include "libGLESv2/Framebuffer.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000016
17static DWORD currentTLS = TLS_OUT_OF_INDEXES;
18
daniel@transgaming.comfad16ed2012-10-17 18:24:01 +000019extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000020{
21 switch (reason)
22 {
23 case DLL_PROCESS_ATTACH:
24 {
25 currentTLS = TlsAlloc();
26
27 if (currentTLS == TLS_OUT_OF_INDEXES)
28 {
29 return FALSE;
30 }
31 }
32 // Fall throught to initialize index
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000033 case DLL_THREAD_ATTACH:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034 {
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000035 gl::Current *current = (gl::Current*)LocalAlloc(LPTR, sizeof(gl::Current));
36
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037 if (current)
38 {
39 TlsSetValue(currentTLS, current);
40
41 current->context = NULL;
42 current->display = NULL;
43 }
44 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000045 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000046 case DLL_THREAD_DETACH:
47 {
48 void *current = TlsGetValue(currentTLS);
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000049
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000050 if (current)
51 {
52 LocalFree((HLOCAL)current);
53 }
54 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000055 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000056 case DLL_PROCESS_DETACH:
57 {
58 void *current = TlsGetValue(currentTLS);
59
60 if (current)
61 {
62 LocalFree((HLOCAL)current);
63 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000064
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000065 TlsFree(currentTLS);
66 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000067 break;
68 default:
69 break;
70 }
71
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072 return TRUE;
73}
74
75namespace gl
76{
77void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
78{
79 Current *current = (Current*)TlsGetValue(currentTLS);
80
81 current->context = context;
82 current->display = display;
83
84 if (context && display && surface)
85 {
daniel@transgaming.comad629872012-11-28 19:32:06 +000086 context->makeCurrent(surface);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000087 }
88}
89
90Context *getContext()
91{
92 Current *current = (Current*)TlsGetValue(currentTLS);
93
94 return current->context;
95}
96
daniel@transgaming.com9d788502011-11-09 17:46:55 +000097Context *getNonLostContext()
98{
99 Context *context = getContext();
100
daniel@transgaming.com82b28912011-12-12 21:01:35 +0000101 if (context)
102 {
103 if (context->isContextLost())
104 {
105 error(GL_OUT_OF_MEMORY);
106 return NULL;
107 }
108 else
109 {
110 return context;
111 }
112 }
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000113 return NULL;
114}
115
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000116egl::Display *getDisplay()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000117{
118 Current *current = (Current*)TlsGetValue(currentTLS);
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000119
120 return current->display;
121}
122
daniel@transgaming.com78d44862011-11-09 17:46:33 +0000123bool checkDeviceLost(HRESULT errorCode)
124{
125 egl::Display *display = NULL;
126
127 if (isDeviceLostError(errorCode))
128 {
daniel@transgaming.com09fcc9f2011-11-09 17:46:47 +0000129 display = gl::getDisplay();
130 display->notifyDeviceLost();
daniel@transgaming.com78d44862011-11-09 17:46:33 +0000131 return true;
132 }
133 return false;
134}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135}
136
137// Records an error code
138void error(GLenum errorCode)
139{
140 gl::Context *context = glGetCurrentContext();
141
142 if (context)
143 {
144 switch (errorCode)
145 {
146 case GL_INVALID_ENUM:
147 context->recordInvalidEnum();
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000148 TRACE("\t! Error generated: invalid enum\n");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000149 break;
150 case GL_INVALID_VALUE:
151 context->recordInvalidValue();
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000152 TRACE("\t! Error generated: invalid value\n");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000153 break;
154 case GL_INVALID_OPERATION:
155 context->recordInvalidOperation();
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000156 TRACE("\t! Error generated: invalid operation\n");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000157 break;
158 case GL_OUT_OF_MEMORY:
159 context->recordOutOfMemory();
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000160 TRACE("\t! Error generated: out of memory\n");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000161 break;
162 case GL_INVALID_FRAMEBUFFER_OPERATION:
163 context->recordInvalidFramebufferOperation();
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000164 TRACE("\t! Error generated: invalid framebuffer operation\n");
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000165 break;
166 default: UNREACHABLE();
167 }
168 }
169}