xref: /aosp_15_r20/external/angle/src/libGLESv2/global_state.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // global_state.cpp : Implements functions for querying the thread-local GL and EGL state.
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "libGLESv2/global_state.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "common/platform.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "common/system_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/ErrorStrings.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Thread.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libGLESv2/egl_stubs_autogen.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libGLESv2/resource.h"
18*8975f5c5SAndroid Build Coastguard Worker 
19*8975f5c5SAndroid Build Coastguard Worker #include <atomic>
20*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE)
21*8975f5c5SAndroid Build Coastguard Worker #    include <dispatch/dispatch.h>
22*8975f5c5SAndroid Build Coastguard Worker #endif
23*8975f5c5SAndroid Build Coastguard Worker namespace egl
24*8975f5c5SAndroid Build Coastguard Worker {
25*8975f5c5SAndroid Build Coastguard Worker namespace
26*8975f5c5SAndroid Build Coastguard Worker {
27*8975f5c5SAndroid Build Coastguard Worker ANGLE_REQUIRE_CONSTANT_INIT gl::Context *g_LastContext(nullptr);
28*8975f5c5SAndroid Build Coastguard Worker static_assert(std::is_trivially_destructible<decltype(g_LastContext)>::value,
29*8975f5c5SAndroid Build Coastguard Worker               "global last context is not trivially destructible");
30*8975f5c5SAndroid Build Coastguard Worker 
31*8975f5c5SAndroid Build Coastguard Worker bool g_EGLValidationEnabled = true;
32*8975f5c5SAndroid Build Coastguard Worker 
33*8975f5c5SAndroid Build Coastguard Worker // Called only on Android platform
ThreadCleanupCallback(void * ptr)34*8975f5c5SAndroid Build Coastguard Worker [[maybe_unused]] void ThreadCleanupCallback(void *ptr)
35*8975f5c5SAndroid Build Coastguard Worker {
36*8975f5c5SAndroid Build Coastguard Worker     egl::Thread *thread = static_cast<egl::Thread *>(ptr);
37*8975f5c5SAndroid Build Coastguard Worker     ASSERT(thread);
38*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SCOPED_GLOBAL_EGL_AND_EGL_SYNC_LOCK();
39*8975f5c5SAndroid Build Coastguard Worker     // ReleaseThread() and makeCurrent() inside will perform:
40*8975f5c5SAndroid Build Coastguard Worker     // - destroy Context if it was already marked for destruction;
41*8975f5c5SAndroid Build Coastguard Worker     // - invalidate Context if Display was already terminated by app;
42*8975f5c5SAndroid Build Coastguard Worker     // - perform Display termination when no active threads (and current Contexts);
43*8975f5c5SAndroid Build Coastguard Worker     // - release any invalid objects in case if Display was not terminated.
44*8975f5c5SAndroid Build Coastguard Worker     (void)ReleaseThread(thread);
45*8975f5c5SAndroid Build Coastguard Worker }
46*8975f5c5SAndroid Build Coastguard Worker 
AllocateCurrentThread()47*8975f5c5SAndroid Build Coastguard Worker Thread *AllocateCurrentThread()
48*8975f5c5SAndroid Build Coastguard Worker {
49*8975f5c5SAndroid Build Coastguard Worker     Thread *thread;
50*8975f5c5SAndroid Build Coastguard Worker     {
51*8975f5c5SAndroid Build Coastguard Worker         // Global thread intentionally leaked.
52*8975f5c5SAndroid Build Coastguard Worker         // Display TLS data is also intentionally leaked.
53*8975f5c5SAndroid Build Coastguard Worker         ANGLE_SCOPED_DISABLE_LSAN();
54*8975f5c5SAndroid Build Coastguard Worker         thread = new Thread();
55*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE) || defined(ANGLE_USE_STATIC_THREAD_LOCAL_VARIABLES)
56*8975f5c5SAndroid Build Coastguard Worker         SetCurrentThreadTLS(thread);
57*8975f5c5SAndroid Build Coastguard Worker #else
58*8975f5c5SAndroid Build Coastguard Worker         gCurrentThread = thread;
59*8975f5c5SAndroid Build Coastguard Worker #endif
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker         Display::InitTLS();
62*8975f5c5SAndroid Build Coastguard Worker     }
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker     // Initialize current-context TLS slot
65*8975f5c5SAndroid Build Coastguard Worker     gl::SetCurrentValidContext(nullptr);
66*8975f5c5SAndroid Build Coastguard Worker 
67*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_ANDROID)
68*8975f5c5SAndroid Build Coastguard Worker     static pthread_once_t keyOnce                 = PTHREAD_ONCE_INIT;
69*8975f5c5SAndroid Build Coastguard Worker     static angle::TLSIndex gThreadCleanupTLSIndex = TLS_INVALID_INDEX;
70*8975f5c5SAndroid Build Coastguard Worker 
71*8975f5c5SAndroid Build Coastguard Worker     // Create thread cleanup TLS slot
72*8975f5c5SAndroid Build Coastguard Worker     auto CreateThreadCleanupTLSIndex = []() {
73*8975f5c5SAndroid Build Coastguard Worker         gThreadCleanupTLSIndex = angle::CreateTLSIndex(ThreadCleanupCallback);
74*8975f5c5SAndroid Build Coastguard Worker     };
75*8975f5c5SAndroid Build Coastguard Worker     pthread_once(&keyOnce, CreateThreadCleanupTLSIndex);
76*8975f5c5SAndroid Build Coastguard Worker     ASSERT(gThreadCleanupTLSIndex != TLS_INVALID_INDEX);
77*8975f5c5SAndroid Build Coastguard Worker 
78*8975f5c5SAndroid Build Coastguard Worker     // Initialize thread cleanup TLS slot
79*8975f5c5SAndroid Build Coastguard Worker     angle::SetTLSValue(gThreadCleanupTLSIndex, thread);
80*8975f5c5SAndroid Build Coastguard Worker #endif  // ANGLE_PLATFORM_ANDROID
81*8975f5c5SAndroid Build Coastguard Worker 
82*8975f5c5SAndroid Build Coastguard Worker     ASSERT(thread);
83*8975f5c5SAndroid Build Coastguard Worker     return thread;
84*8975f5c5SAndroid Build Coastguard Worker }
85*8975f5c5SAndroid Build Coastguard Worker 
86*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE)
89*8975f5c5SAndroid Build Coastguard Worker // TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause
90*8975f5c5SAndroid Build Coastguard Worker // excessive memory use. Temporarily avoid it by using pthread's thread
91*8975f5c5SAndroid Build Coastguard Worker // local storage instead.
92*8975f5c5SAndroid Build Coastguard Worker // https://bugs.webkit.org/show_bug.cgi?id=228240
93*8975f5c5SAndroid Build Coastguard Worker 
GetCurrentThreadTLSIndex()94*8975f5c5SAndroid Build Coastguard Worker static angle::TLSIndex GetCurrentThreadTLSIndex()
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker     static angle::TLSIndex CurrentThreadIndex = TLS_INVALID_INDEX;
97*8975f5c5SAndroid Build Coastguard Worker     static dispatch_once_t once;
98*8975f5c5SAndroid Build Coastguard Worker     dispatch_once(&once, ^{
99*8975f5c5SAndroid Build Coastguard Worker       ASSERT(CurrentThreadIndex == TLS_INVALID_INDEX);
100*8975f5c5SAndroid Build Coastguard Worker       CurrentThreadIndex = angle::CreateTLSIndex(nullptr);
101*8975f5c5SAndroid Build Coastguard Worker     });
102*8975f5c5SAndroid Build Coastguard Worker     return CurrentThreadIndex;
103*8975f5c5SAndroid Build Coastguard Worker }
GetCurrentThreadTLS()104*8975f5c5SAndroid Build Coastguard Worker Thread *GetCurrentThreadTLS()
105*8975f5c5SAndroid Build Coastguard Worker {
106*8975f5c5SAndroid Build Coastguard Worker     angle::TLSIndex CurrentThreadIndex = GetCurrentThreadTLSIndex();
107*8975f5c5SAndroid Build Coastguard Worker     ASSERT(CurrentThreadIndex != TLS_INVALID_INDEX);
108*8975f5c5SAndroid Build Coastguard Worker     return static_cast<Thread *>(angle::GetTLSValue(CurrentThreadIndex));
109*8975f5c5SAndroid Build Coastguard Worker }
SetCurrentThreadTLS(Thread * thread)110*8975f5c5SAndroid Build Coastguard Worker void SetCurrentThreadTLS(Thread *thread)
111*8975f5c5SAndroid Build Coastguard Worker {
112*8975f5c5SAndroid Build Coastguard Worker     angle::TLSIndex CurrentThreadIndex = GetCurrentThreadTLSIndex();
113*8975f5c5SAndroid Build Coastguard Worker     ASSERT(CurrentThreadIndex != TLS_INVALID_INDEX);
114*8975f5c5SAndroid Build Coastguard Worker     angle::SetTLSValue(CurrentThreadIndex, thread);
115*8975f5c5SAndroid Build Coastguard Worker }
116*8975f5c5SAndroid Build Coastguard Worker #elif defined(ANGLE_USE_STATIC_THREAD_LOCAL_VARIABLES)
117*8975f5c5SAndroid Build Coastguard Worker static thread_local Thread *gCurrentThread = nullptr;
GetCurrentThreadTLS()118*8975f5c5SAndroid Build Coastguard Worker Thread *GetCurrentThreadTLS()
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker     return gCurrentThread;
121*8975f5c5SAndroid Build Coastguard Worker }
SetCurrentThreadTLS(Thread * thread)122*8975f5c5SAndroid Build Coastguard Worker void SetCurrentThreadTLS(Thread *thread)
123*8975f5c5SAndroid Build Coastguard Worker {
124*8975f5c5SAndroid Build Coastguard Worker     gCurrentThread = thread;
125*8975f5c5SAndroid Build Coastguard Worker }
126*8975f5c5SAndroid Build Coastguard Worker #else
127*8975f5c5SAndroid Build Coastguard Worker thread_local Thread *gCurrentThread = nullptr;
128*8975f5c5SAndroid Build Coastguard Worker #endif
129*8975f5c5SAndroid Build Coastguard Worker 
GetGlobalLastContext()130*8975f5c5SAndroid Build Coastguard Worker gl::Context *GetGlobalLastContext()
131*8975f5c5SAndroid Build Coastguard Worker {
132*8975f5c5SAndroid Build Coastguard Worker     return g_LastContext;
133*8975f5c5SAndroid Build Coastguard Worker }
134*8975f5c5SAndroid Build Coastguard Worker 
SetGlobalLastContext(gl::Context * context)135*8975f5c5SAndroid Build Coastguard Worker void SetGlobalLastContext(gl::Context *context)
136*8975f5c5SAndroid Build Coastguard Worker {
137*8975f5c5SAndroid Build Coastguard Worker     g_LastContext = context;
138*8975f5c5SAndroid Build Coastguard Worker }
139*8975f5c5SAndroid Build Coastguard Worker 
140*8975f5c5SAndroid Build Coastguard Worker // This function causes an MSAN false positive, which is muted. See https://crbug.com/1211047
141*8975f5c5SAndroid Build Coastguard Worker // It also causes a flaky false positive in TSAN. http://crbug.com/1223970
GetCurrentThread()142*8975f5c5SAndroid Build Coastguard Worker ANGLE_NO_SANITIZE_MEMORY ANGLE_NO_SANITIZE_THREAD Thread *GetCurrentThread()
143*8975f5c5SAndroid Build Coastguard Worker {
144*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE) || defined(ANGLE_USE_STATIC_THREAD_LOCAL_VARIABLES)
145*8975f5c5SAndroid Build Coastguard Worker     Thread *current = GetCurrentThreadTLS();
146*8975f5c5SAndroid Build Coastguard Worker #else
147*8975f5c5SAndroid Build Coastguard Worker     Thread *current = gCurrentThread;
148*8975f5c5SAndroid Build Coastguard Worker #endif
149*8975f5c5SAndroid Build Coastguard Worker     return (current ? current : AllocateCurrentThread());
150*8975f5c5SAndroid Build Coastguard Worker }
151*8975f5c5SAndroid Build Coastguard Worker 
SetContextCurrent(Thread * thread,gl::Context * context)152*8975f5c5SAndroid Build Coastguard Worker void SetContextCurrent(Thread *thread, gl::Context *context)
153*8975f5c5SAndroid Build Coastguard Worker {
154*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE) || defined(ANGLE_USE_STATIC_THREAD_LOCAL_VARIABLES)
155*8975f5c5SAndroid Build Coastguard Worker     Thread *currentThread = GetCurrentThreadTLS();
156*8975f5c5SAndroid Build Coastguard Worker #else
157*8975f5c5SAndroid Build Coastguard Worker     Thread *currentThread = gCurrentThread;
158*8975f5c5SAndroid Build Coastguard Worker #endif
159*8975f5c5SAndroid Build Coastguard Worker     ASSERT(currentThread);
160*8975f5c5SAndroid Build Coastguard Worker     currentThread->setCurrent(context);
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker     gl::SetCurrentValidContext(context);
163*8975f5c5SAndroid Build Coastguard Worker 
164*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
165*8975f5c5SAndroid Build Coastguard Worker     DirtyContextIfNeeded(context);
166*8975f5c5SAndroid Build Coastguard Worker #endif
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker 
ScopedSyncCurrentContextFromThread(egl::Thread * thread)169*8975f5c5SAndroid Build Coastguard Worker ScopedSyncCurrentContextFromThread::ScopedSyncCurrentContextFromThread(egl::Thread *thread)
170*8975f5c5SAndroid Build Coastguard Worker     : mThread(thread)
171*8975f5c5SAndroid Build Coastguard Worker {
172*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mThread);
173*8975f5c5SAndroid Build Coastguard Worker }
174*8975f5c5SAndroid Build Coastguard Worker 
~ScopedSyncCurrentContextFromThread()175*8975f5c5SAndroid Build Coastguard Worker ScopedSyncCurrentContextFromThread::~ScopedSyncCurrentContextFromThread()
176*8975f5c5SAndroid Build Coastguard Worker {
177*8975f5c5SAndroid Build Coastguard Worker     SetContextCurrent(mThread, mThread->getContext());
178*8975f5c5SAndroid Build Coastguard Worker }
179*8975f5c5SAndroid Build Coastguard Worker 
SetEGLValidationEnabled(bool enabled)180*8975f5c5SAndroid Build Coastguard Worker void SetEGLValidationEnabled(bool enabled)
181*8975f5c5SAndroid Build Coastguard Worker {
182*8975f5c5SAndroid Build Coastguard Worker     g_EGLValidationEnabled = enabled;
183*8975f5c5SAndroid Build Coastguard Worker }
184*8975f5c5SAndroid Build Coastguard Worker 
IsEGLValidationEnabled()185*8975f5c5SAndroid Build Coastguard Worker bool IsEGLValidationEnabled()
186*8975f5c5SAndroid Build Coastguard Worker {
187*8975f5c5SAndroid Build Coastguard Worker     return g_EGLValidationEnabled;
188*8975f5c5SAndroid Build Coastguard Worker }
189*8975f5c5SAndroid Build Coastguard Worker 
190*8975f5c5SAndroid Build Coastguard Worker }  // namespace egl
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker namespace gl
193*8975f5c5SAndroid Build Coastguard Worker {
GenerateContextLostErrorOnContext(Context * context)194*8975f5c5SAndroid Build Coastguard Worker void GenerateContextLostErrorOnContext(Context *context)
195*8975f5c5SAndroid Build Coastguard Worker {
196*8975f5c5SAndroid Build Coastguard Worker     if (context && context->isContextLost())
197*8975f5c5SAndroid Build Coastguard Worker     {
198*8975f5c5SAndroid Build Coastguard Worker         context->getMutableErrorSetForValidation()->validationError(
199*8975f5c5SAndroid Build Coastguard Worker             angle::EntryPoint::Invalid, GL_CONTEXT_LOST, err::kContextLost);
200*8975f5c5SAndroid Build Coastguard Worker     }
201*8975f5c5SAndroid Build Coastguard Worker }
202*8975f5c5SAndroid Build Coastguard Worker 
GenerateContextLostErrorOnCurrentGlobalContext()203*8975f5c5SAndroid Build Coastguard Worker void GenerateContextLostErrorOnCurrentGlobalContext()
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker     // If the client starts issuing GL calls before ANGLE has had a chance to initialize,
206*8975f5c5SAndroid Build Coastguard Worker     // GenerateContextLostErrorOnCurrentGlobalContext can be called before AllocateCurrentThread has
207*8975f5c5SAndroid Build Coastguard Worker     // had a chance to run. Calling GetCurrentThread() ensures that TLS thread state is set up.
208*8975f5c5SAndroid Build Coastguard Worker     egl::GetCurrentThread();
209*8975f5c5SAndroid Build Coastguard Worker 
210*8975f5c5SAndroid Build Coastguard Worker     GenerateContextLostErrorOnContext(GetGlobalContext());
211*8975f5c5SAndroid Build Coastguard Worker }
212*8975f5c5SAndroid Build Coastguard Worker }  // namespace gl
213*8975f5c5SAndroid Build Coastguard Worker 
214*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_STATIC)
215*8975f5c5SAndroid Build Coastguard Worker namespace egl
216*8975f5c5SAndroid Build Coastguard Worker {
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker namespace
219*8975f5c5SAndroid Build Coastguard Worker {
220*8975f5c5SAndroid Build Coastguard Worker 
DeallocateCurrentThread()221*8975f5c5SAndroid Build Coastguard Worker void DeallocateCurrentThread()
222*8975f5c5SAndroid Build Coastguard Worker {
223*8975f5c5SAndroid Build Coastguard Worker     SafeDelete(gCurrentThread);
224*8975f5c5SAndroid Build Coastguard Worker }
225*8975f5c5SAndroid Build Coastguard Worker 
InitializeProcess()226*8975f5c5SAndroid Build Coastguard Worker bool InitializeProcess()
227*8975f5c5SAndroid Build Coastguard Worker {
228*8975f5c5SAndroid Build Coastguard Worker     EnsureDebugAllocated();
229*8975f5c5SAndroid Build Coastguard Worker     AllocateGlobalMutex();
230*8975f5c5SAndroid Build Coastguard Worker     return AllocateCurrentThread() != nullptr;
231*8975f5c5SAndroid Build Coastguard Worker }
232*8975f5c5SAndroid Build Coastguard Worker 
TerminateProcess()233*8975f5c5SAndroid Build Coastguard Worker void TerminateProcess()
234*8975f5c5SAndroid Build Coastguard Worker {
235*8975f5c5SAndroid Build Coastguard Worker     DeallocateDebug();
236*8975f5c5SAndroid Build Coastguard Worker     DeallocateGlobalMutex();
237*8975f5c5SAndroid Build Coastguard Worker     DeallocateCurrentThread();
238*8975f5c5SAndroid Build Coastguard Worker }
239*8975f5c5SAndroid Build Coastguard Worker 
240*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
241*8975f5c5SAndroid Build Coastguard Worker 
242*8975f5c5SAndroid Build Coastguard Worker }  // namespace egl
243*8975f5c5SAndroid Build Coastguard Worker 
244*8975f5c5SAndroid Build Coastguard Worker namespace
245*8975f5c5SAndroid Build Coastguard Worker {
246*8975f5c5SAndroid Build Coastguard Worker // The following WaitForDebugger code is based on SwiftShader. See:
247*8975f5c5SAndroid Build Coastguard Worker // https://cs.chromium.org/chromium/src/third_party/swiftshader/src/Vulkan/main.cpp
248*8975f5c5SAndroid Build Coastguard Worker #    if defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
DebuggerWaitDialogProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)249*8975f5c5SAndroid Build Coastguard Worker INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
250*8975f5c5SAndroid Build Coastguard Worker {
251*8975f5c5SAndroid Build Coastguard Worker     RECT rect;
252*8975f5c5SAndroid Build Coastguard Worker 
253*8975f5c5SAndroid Build Coastguard Worker     switch (uMsg)
254*8975f5c5SAndroid Build Coastguard Worker     {
255*8975f5c5SAndroid Build Coastguard Worker         case WM_INITDIALOG:
256*8975f5c5SAndroid Build Coastguard Worker             ::GetWindowRect(GetDesktopWindow(), &rect);
257*8975f5c5SAndroid Build Coastguard Worker             ::SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
258*8975f5c5SAndroid Build Coastguard Worker             ::SetTimer(hwnd, 1, 100, NULL);
259*8975f5c5SAndroid Build Coastguard Worker             return TRUE;
260*8975f5c5SAndroid Build Coastguard Worker         case WM_COMMAND:
261*8975f5c5SAndroid Build Coastguard Worker             if (LOWORD(wParam) == IDCANCEL)
262*8975f5c5SAndroid Build Coastguard Worker             {
263*8975f5c5SAndroid Build Coastguard Worker                 ::EndDialog(hwnd, 0);
264*8975f5c5SAndroid Build Coastguard Worker             }
265*8975f5c5SAndroid Build Coastguard Worker             break;
266*8975f5c5SAndroid Build Coastguard Worker         case WM_TIMER:
267*8975f5c5SAndroid Build Coastguard Worker             if (angle::IsDebuggerAttached())
268*8975f5c5SAndroid Build Coastguard Worker             {
269*8975f5c5SAndroid Build Coastguard Worker                 ::EndDialog(hwnd, 0);
270*8975f5c5SAndroid Build Coastguard Worker             }
271*8975f5c5SAndroid Build Coastguard Worker     }
272*8975f5c5SAndroid Build Coastguard Worker 
273*8975f5c5SAndroid Build Coastguard Worker     return FALSE;
274*8975f5c5SAndroid Build Coastguard Worker }
275*8975f5c5SAndroid Build Coastguard Worker 
WaitForDebugger(HINSTANCE instance)276*8975f5c5SAndroid Build Coastguard Worker void WaitForDebugger(HINSTANCE instance)
277*8975f5c5SAndroid Build Coastguard Worker {
278*8975f5c5SAndroid Build Coastguard Worker     if (angle::IsDebuggerAttached())
279*8975f5c5SAndroid Build Coastguard Worker         return;
280*8975f5c5SAndroid Build Coastguard Worker 
281*8975f5c5SAndroid Build Coastguard Worker     HRSRC dialog = ::FindResourceA(instance, MAKEINTRESOURCEA(IDD_DIALOG1), MAKEINTRESOURCEA(5));
282*8975f5c5SAndroid Build Coastguard Worker     if (!dialog)
283*8975f5c5SAndroid Build Coastguard Worker     {
284*8975f5c5SAndroid Build Coastguard Worker         printf("Error finding wait for debugger dialog. Error %lu.\n", ::GetLastError());
285*8975f5c5SAndroid Build Coastguard Worker         return;
286*8975f5c5SAndroid Build Coastguard Worker     }
287*8975f5c5SAndroid Build Coastguard Worker 
288*8975f5c5SAndroid Build Coastguard Worker     DLGTEMPLATE *dialogTemplate = reinterpret_cast<DLGTEMPLATE *>(::LoadResource(instance, dialog));
289*8975f5c5SAndroid Build Coastguard Worker     ::DialogBoxIndirectA(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);
290*8975f5c5SAndroid Build Coastguard Worker }
291*8975f5c5SAndroid Build Coastguard Worker #    else
292*8975f5c5SAndroid Build Coastguard Worker void WaitForDebugger(HINSTANCE instance) {}
293*8975f5c5SAndroid Build Coastguard Worker #    endif  // defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
294*8975f5c5SAndroid Build Coastguard Worker }  // namespace
295*8975f5c5SAndroid Build Coastguard Worker 
DllMain(HINSTANCE instance,DWORD reason,LPVOID)296*8975f5c5SAndroid Build Coastguard Worker extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)
297*8975f5c5SAndroid Build Coastguard Worker {
298*8975f5c5SAndroid Build Coastguard Worker     switch (reason)
299*8975f5c5SAndroid Build Coastguard Worker     {
300*8975f5c5SAndroid Build Coastguard Worker         case DLL_PROCESS_ATTACH:
301*8975f5c5SAndroid Build Coastguard Worker             if (angle::GetBoolEnvironmentVar("ANGLE_WAIT_FOR_DEBUGGER"))
302*8975f5c5SAndroid Build Coastguard Worker             {
303*8975f5c5SAndroid Build Coastguard Worker                 WaitForDebugger(instance);
304*8975f5c5SAndroid Build Coastguard Worker             }
305*8975f5c5SAndroid Build Coastguard Worker             return static_cast<BOOL>(egl::InitializeProcess());
306*8975f5c5SAndroid Build Coastguard Worker 
307*8975f5c5SAndroid Build Coastguard Worker         case DLL_THREAD_ATTACH:
308*8975f5c5SAndroid Build Coastguard Worker             return static_cast<BOOL>(egl::AllocateCurrentThread() != nullptr);
309*8975f5c5SAndroid Build Coastguard Worker 
310*8975f5c5SAndroid Build Coastguard Worker         case DLL_THREAD_DETACH:
311*8975f5c5SAndroid Build Coastguard Worker             egl::DeallocateCurrentThread();
312*8975f5c5SAndroid Build Coastguard Worker             break;
313*8975f5c5SAndroid Build Coastguard Worker 
314*8975f5c5SAndroid Build Coastguard Worker         case DLL_PROCESS_DETACH:
315*8975f5c5SAndroid Build Coastguard Worker             egl::TerminateProcess();
316*8975f5c5SAndroid Build Coastguard Worker             break;
317*8975f5c5SAndroid Build Coastguard Worker     }
318*8975f5c5SAndroid Build Coastguard Worker 
319*8975f5c5SAndroid Build Coastguard Worker     return TRUE;
320*8975f5c5SAndroid Build Coastguard Worker }
321*8975f5c5SAndroid Build Coastguard Worker #endif  // defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_STATIC)
322