blob: 4444d1ac231786fe8a763d9690dd91ea80c3227c [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"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000010#include "libGLESv2/Context.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000011
Geoff Lang44fa7592014-05-30 11:50:07 -040012#include "common/tls.h"
13
14static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000015
Jamie Madill7a934372013-12-06 18:17:48 -050016namespace gl
17{
18
19Current *AllocateCurrent()
20{
Geoff Lang44fa7592014-05-30 11:50:07 -040021 ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
22 if (currentTLS == TLS_OUT_OF_INDEXES)
Jamie Madill7a934372013-12-06 18:17:48 -050023 {
Jamie Madill7a934372013-12-06 18:17:48 -050024 return NULL;
25 }
26
Geoff Lang44fa7592014-05-30 11:50:07 -040027 Current *current = new Current();
Jamie Madill7a934372013-12-06 18:17:48 -050028 current->context = NULL;
29 current->display = NULL;
30
Geoff Lang44fa7592014-05-30 11:50:07 -040031 if (!SetTLSValue(currentTLS, current))
32 {
33 ERR("Could not set thread local storage.");
34 return NULL;
35 }
36
Jamie Madill7a934372013-12-06 18:17:48 -050037 return current;
38}
39
40void DeallocateCurrent()
41{
Geoff Lang44fa7592014-05-30 11:50:07 -040042 Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
43 SafeDelete(current);
44 SetTLSValue(currentTLS, NULL);
Jamie Madill7a934372013-12-06 18:17:48 -050045}
46
47}
48
daniel@transgaming.comfad16ed2012-10-17 18:24:01 +000049extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000050{
51 switch (reason)
52 {
53 case DLL_PROCESS_ATTACH:
54 {
Geoff Lang44fa7592014-05-30 11:50:07 -040055 currentTLS = CreateTLSIndex();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000056 if (currentTLS == TLS_OUT_OF_INDEXES)
57 {
58 return FALSE;
59 }
60 }
Geoff Lang44fa7592014-05-30 11:50:07 -040061 // Fall through to initialize index
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000062 case DLL_THREAD_ATTACH:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000063 {
Jamie Madill7a934372013-12-06 18:17:48 -050064 gl::AllocateCurrent();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000065 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000066 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000067 case DLL_THREAD_DETACH:
68 {
Jamie Madill7a934372013-12-06 18:17:48 -050069 gl::DeallocateCurrent();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000071 break;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072 case DLL_PROCESS_DETACH:
73 {
Jamie Madill7a934372013-12-06 18:17:48 -050074 gl::DeallocateCurrent();
Geoff Lang44fa7592014-05-30 11:50:07 -040075 DestroyTLSIndex(currentTLS);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000076 }
daniel@transgaming.comfab5a1a2010-03-11 19:22:30 +000077 break;
78 default:
79 break;
80 }
81
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000082 return TRUE;
83}
84
85namespace gl
86{
Jamie Madill7a934372013-12-06 18:17:48 -050087
88Current *GetCurrentData()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000089{
Geoff Lang44fa7592014-05-30 11:50:07 -040090 Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091
Jamie Madill7a934372013-12-06 18:17:48 -050092 // ANGLE issue 488: when the dll is loaded after thread initialization,
93 // thread local storage (current) might not exist yet.
94 return (current ? current : AllocateCurrent());
95}
96
97void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
98{
99 Current *current = GetCurrentData();
100
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101 current->context = context;
102 current->display = display;
103
104 if (context && display && surface)
105 {
daniel@transgaming.comad629872012-11-28 19:32:06 +0000106 context->makeCurrent(surface);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107 }
108}
109
110Context *getContext()
111{
Jamie Madill7a934372013-12-06 18:17:48 -0500112 Current *current = GetCurrentData();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000113
114 return current->context;
115}
116
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000117Context *getNonLostContext()
118{
119 Context *context = getContext();
Geoff Lang44fa7592014-05-30 11:50:07 -0400120
daniel@transgaming.com82b28912011-12-12 21:01:35 +0000121 if (context)
122 {
123 if (context->isContextLost())
124 {
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000125 gl::error(GL_OUT_OF_MEMORY);
daniel@transgaming.com82b28912011-12-12 21:01:35 +0000126 return NULL;
127 }
128 else
129 {
130 return context;
131 }
132 }
daniel@transgaming.com9d788502011-11-09 17:46:55 +0000133 return NULL;
134}
135
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000136egl::Display *getDisplay()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137{
Jamie Madill7a934372013-12-06 18:17:48 -0500138 Current *current = GetCurrentData();
daniel@transgaming.comae072af2010-05-05 18:47:28 +0000139
140 return current->display;
141}
142
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000143// Records an error code
144void error(GLenum errorCode)
145{
146 gl::Context *context = glGetCurrentContext();
Geoff Langda5777c2014-07-11 09:52:58 -0400147 context->recordError(Error(errorCode));
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000148
Geoff Langda5777c2014-07-11 09:52:58 -0400149 switch (errorCode)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150 {
Geoff Langda5777c2014-07-11 09:52:58 -0400151 case GL_INVALID_ENUM:
152 TRACE("\t! Error generated: invalid enum\n");
153 break;
154 case GL_INVALID_VALUE:
155 TRACE("\t! Error generated: invalid value\n");
156 break;
157 case GL_INVALID_OPERATION:
158 TRACE("\t! Error generated: invalid operation\n");
159 break;
160 case GL_OUT_OF_MEMORY:
161 TRACE("\t! Error generated: out of memory\n");
162 break;
163 case GL_INVALID_FRAMEBUFFER_OPERATION:
164 TRACE("\t! Error generated: invalid framebuffer operation\n");
165 break;
166 default: UNREACHABLE();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000167 }
168}
shannon.woods@transgaming.com779aa262013-02-28 23:04:58 +0000169
170}
171