Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/src/libGLESv2/global_state.cpp
1693 views
1
//
2
// Copyright 2014 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
// global_state.cpp : Implements functions for querying the thread-local GL and EGL state.
8
9
#include "libGLESv2/global_state.h"
10
11
#include "common/debug.h"
12
#include "common/platform.h"
13
#include "common/system_utils.h"
14
#include "libANGLE/ErrorStrings.h"
15
#include "libANGLE/Thread.h"
16
#include "libGLESv2/resource.h"
17
18
#include <atomic>
19
20
namespace egl
21
{
22
namespace
23
{
24
ANGLE_REQUIRE_CONSTANT_INIT std::atomic<angle::GlobalMutex *> g_Mutex(nullptr);
25
static_assert(std::is_trivially_destructible<decltype(g_Mutex)>::value,
26
"global mutex is not trivially destructible");
27
28
ANGLE_REQUIRE_CONSTANT_INIT gl::Context *g_LastContext(nullptr);
29
static_assert(std::is_trivially_destructible<decltype(g_LastContext)>::value,
30
"global last context is not trivially destructible");
31
32
void SetContextToAndroidOpenGLTLSSlot(gl::Context *value)
33
{
34
#if defined(ANGLE_PLATFORM_ANDROID)
35
if (angle::gUseAndroidOpenGLTlsSlot)
36
{
37
ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot] = static_cast<void *>(value);
38
}
39
#endif
40
}
41
42
Thread *AllocateCurrentThread()
43
{
44
{
45
// Global thread intentionally leaked
46
ANGLE_SCOPED_DISABLE_LSAN();
47
gCurrentThread = new Thread();
48
}
49
50
// Initialize fast TLS slot
51
SetContextToAndroidOpenGLTLSSlot(nullptr);
52
gl::gCurrentValidContext = nullptr;
53
54
return gCurrentThread;
55
}
56
57
void AllocateMutex()
58
{
59
if (g_Mutex == nullptr)
60
{
61
std::unique_ptr<angle::GlobalMutex> newMutex(new angle::GlobalMutex());
62
angle::GlobalMutex *expected = nullptr;
63
if (g_Mutex.compare_exchange_strong(expected, newMutex.get()))
64
{
65
newMutex.release();
66
}
67
}
68
}
69
70
} // anonymous namespace
71
72
thread_local Thread *gCurrentThread = nullptr;
73
74
angle::GlobalMutex &GetGlobalMutex()
75
{
76
AllocateMutex();
77
return *g_Mutex;
78
}
79
80
gl::Context *GetGlobalLastContext()
81
{
82
return g_LastContext;
83
}
84
85
void SetGlobalLastContext(gl::Context *context)
86
{
87
g_LastContext = context;
88
}
89
90
// This function causes an MSAN false positive, which is muted. See https://crbug.com/1211047
91
// It also causes a flaky false positive in TSAN. http://crbug.com/1223970
92
ANGLE_NO_SANITIZE_MEMORY ANGLE_NO_SANITIZE_THREAD Thread *GetCurrentThread()
93
{
94
Thread *current = gCurrentThread;
95
return (current ? current : AllocateCurrentThread());
96
}
97
98
void SetContextCurrent(Thread *thread, gl::Context *context)
99
{
100
ASSERT(gCurrentThread == thread);
101
SetContextToAndroidOpenGLTLSSlot(context);
102
gl::gCurrentValidContext = context;
103
#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
104
DirtyContextIfNeeded(context);
105
#endif
106
}
107
108
ScopedSyncCurrentContextFromThread::ScopedSyncCurrentContextFromThread(egl::Thread *thread)
109
: mThread(thread)
110
{
111
ASSERT(mThread);
112
}
113
114
ScopedSyncCurrentContextFromThread::~ScopedSyncCurrentContextFromThread()
115
{
116
SetContextCurrent(mThread, mThread->getContext());
117
}
118
119
} // namespace egl
120
121
namespace gl
122
{
123
void GenerateContextLostErrorOnContext(Context *context)
124
{
125
if (context && context->isContextLost())
126
{
127
context->validationError(GL_CONTEXT_LOST, err::kContextLost);
128
}
129
}
130
131
void GenerateContextLostErrorOnCurrentGlobalContext()
132
{
133
GenerateContextLostErrorOnContext(GetGlobalContext());
134
}
135
} // namespace gl
136
137
#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_STATIC)
138
namespace egl
139
{
140
141
namespace
142
{
143
void DeallocateCurrentThread()
144
{
145
SafeDelete(gCurrentThread);
146
}
147
148
void DeallocateMutex()
149
{
150
angle::GlobalMutex *mutex = g_Mutex.exchange(nullptr);
151
{
152
// Wait for the mutex to become released by other threads before deleting.
153
std::lock_guard<angle::GlobalMutex> lock(*mutex);
154
}
155
SafeDelete(mutex);
156
}
157
158
bool InitializeProcess()
159
{
160
EnsureDebugAllocated();
161
AllocateMutex();
162
return AllocateCurrentThread() != nullptr;
163
}
164
165
void TerminateProcess()
166
{
167
DeallocateDebug();
168
DeallocateMutex();
169
DeallocateCurrentThread();
170
}
171
172
} // anonymous namespace
173
174
} // namespace egl
175
176
namespace
177
{
178
// The following WaitForDebugger code is based on SwiftShader. See:
179
// https://cs.chromium.org/chromium/src/third_party/swiftshader/src/Vulkan/main.cpp
180
# if defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
181
INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
182
{
183
RECT rect;
184
185
switch (uMsg)
186
{
187
case WM_INITDIALOG:
188
::GetWindowRect(GetDesktopWindow(), &rect);
189
::SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
190
::SetTimer(hwnd, 1, 100, NULL);
191
return TRUE;
192
case WM_COMMAND:
193
if (LOWORD(wParam) == IDCANCEL)
194
{
195
::EndDialog(hwnd, 0);
196
}
197
break;
198
case WM_TIMER:
199
if (angle::IsDebuggerAttached())
200
{
201
::EndDialog(hwnd, 0);
202
}
203
}
204
205
return FALSE;
206
}
207
208
void WaitForDebugger(HINSTANCE instance)
209
{
210
if (angle::IsDebuggerAttached())
211
return;
212
213
HRSRC dialog = ::FindResourceA(instance, MAKEINTRESOURCEA(IDD_DIALOG1), MAKEINTRESOURCEA(5));
214
if (!dialog)
215
{
216
printf("Error finding wait for debugger dialog. Error %lu.\n", ::GetLastError());
217
return;
218
}
219
220
DLGTEMPLATE *dialogTemplate = reinterpret_cast<DLGTEMPLATE *>(::LoadResource(instance, dialog));
221
::DialogBoxIndirectA(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
222
}
223
# else
224
void WaitForDebugger(HINSTANCE instance) {}
225
# endif // defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
226
} // namespace
227
228
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
229
{
230
switch (reason)
231
{
232
case DLL_PROCESS_ATTACH:
233
if (angle::GetEnvironmentVar("ANGLE_WAIT_FOR_DEBUGGER") == "1")
234
{
235
WaitForDebugger(instance);
236
}
237
return static_cast<BOOL>(egl::InitializeProcess());
238
239
case DLL_THREAD_ATTACH:
240
return static_cast<BOOL>(egl::AllocateCurrentThread() != nullptr);
241
242
case DLL_THREAD_DETACH:
243
egl::DeallocateCurrentThread();
244
break;
245
246
case DLL_PROCESS_DETACH:
247
egl::TerminateProcess();
248
break;
249
}
250
251
return TRUE;
252
}
253
#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_STATIC)
254
255