Path: blob/main_old/src/libGLESv2/global_state.cpp
1693 views
//1// Copyright 2014 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// global_state.cpp : Implements functions for querying the thread-local GL and EGL state.78#include "libGLESv2/global_state.h"910#include "common/debug.h"11#include "common/platform.h"12#include "common/system_utils.h"13#include "libANGLE/ErrorStrings.h"14#include "libANGLE/Thread.h"15#include "libGLESv2/resource.h"1617#include <atomic>1819namespace egl20{21namespace22{23ANGLE_REQUIRE_CONSTANT_INIT std::atomic<angle::GlobalMutex *> g_Mutex(nullptr);24static_assert(std::is_trivially_destructible<decltype(g_Mutex)>::value,25"global mutex is not trivially destructible");2627ANGLE_REQUIRE_CONSTANT_INIT gl::Context *g_LastContext(nullptr);28static_assert(std::is_trivially_destructible<decltype(g_LastContext)>::value,29"global last context is not trivially destructible");3031void SetContextToAndroidOpenGLTLSSlot(gl::Context *value)32{33#if defined(ANGLE_PLATFORM_ANDROID)34if (angle::gUseAndroidOpenGLTlsSlot)35{36ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot] = static_cast<void *>(value);37}38#endif39}4041Thread *AllocateCurrentThread()42{43{44// Global thread intentionally leaked45ANGLE_SCOPED_DISABLE_LSAN();46gCurrentThread = new Thread();47}4849// Initialize fast TLS slot50SetContextToAndroidOpenGLTLSSlot(nullptr);51gl::gCurrentValidContext = nullptr;5253return gCurrentThread;54}5556void AllocateMutex()57{58if (g_Mutex == nullptr)59{60std::unique_ptr<angle::GlobalMutex> newMutex(new angle::GlobalMutex());61angle::GlobalMutex *expected = nullptr;62if (g_Mutex.compare_exchange_strong(expected, newMutex.get()))63{64newMutex.release();65}66}67}6869} // anonymous namespace7071thread_local Thread *gCurrentThread = nullptr;7273angle::GlobalMutex &GetGlobalMutex()74{75AllocateMutex();76return *g_Mutex;77}7879gl::Context *GetGlobalLastContext()80{81return g_LastContext;82}8384void SetGlobalLastContext(gl::Context *context)85{86g_LastContext = context;87}8889// This function causes an MSAN false positive, which is muted. See https://crbug.com/121104790// It also causes a flaky false positive in TSAN. http://crbug.com/122397091ANGLE_NO_SANITIZE_MEMORY ANGLE_NO_SANITIZE_THREAD Thread *GetCurrentThread()92{93Thread *current = gCurrentThread;94return (current ? current : AllocateCurrentThread());95}9697void SetContextCurrent(Thread *thread, gl::Context *context)98{99ASSERT(gCurrentThread == thread);100SetContextToAndroidOpenGLTLSSlot(context);101gl::gCurrentValidContext = context;102#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)103DirtyContextIfNeeded(context);104#endif105}106107ScopedSyncCurrentContextFromThread::ScopedSyncCurrentContextFromThread(egl::Thread *thread)108: mThread(thread)109{110ASSERT(mThread);111}112113ScopedSyncCurrentContextFromThread::~ScopedSyncCurrentContextFromThread()114{115SetContextCurrent(mThread, mThread->getContext());116}117118} // namespace egl119120namespace gl121{122void GenerateContextLostErrorOnContext(Context *context)123{124if (context && context->isContextLost())125{126context->validationError(GL_CONTEXT_LOST, err::kContextLost);127}128}129130void GenerateContextLostErrorOnCurrentGlobalContext()131{132GenerateContextLostErrorOnContext(GetGlobalContext());133}134} // namespace gl135136#if defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_STATIC)137namespace egl138{139140namespace141{142void DeallocateCurrentThread()143{144SafeDelete(gCurrentThread);145}146147void DeallocateMutex()148{149angle::GlobalMutex *mutex = g_Mutex.exchange(nullptr);150{151// Wait for the mutex to become released by other threads before deleting.152std::lock_guard<angle::GlobalMutex> lock(*mutex);153}154SafeDelete(mutex);155}156157bool InitializeProcess()158{159EnsureDebugAllocated();160AllocateMutex();161return AllocateCurrentThread() != nullptr;162}163164void TerminateProcess()165{166DeallocateDebug();167DeallocateMutex();168DeallocateCurrentThread();169}170171} // anonymous namespace172173} // namespace egl174175namespace176{177// The following WaitForDebugger code is based on SwiftShader. See:178// https://cs.chromium.org/chromium/src/third_party/swiftshader/src/Vulkan/main.cpp179# if defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)180INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)181{182RECT rect;183184switch (uMsg)185{186case WM_INITDIALOG:187::GetWindowRect(GetDesktopWindow(), &rect);188::SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);189::SetTimer(hwnd, 1, 100, NULL);190return TRUE;191case WM_COMMAND:192if (LOWORD(wParam) == IDCANCEL)193{194::EndDialog(hwnd, 0);195}196break;197case WM_TIMER:198if (angle::IsDebuggerAttached())199{200::EndDialog(hwnd, 0);201}202}203204return FALSE;205}206207void WaitForDebugger(HINSTANCE instance)208{209if (angle::IsDebuggerAttached())210return;211212HRSRC dialog = ::FindResourceA(instance, MAKEINTRESOURCEA(IDD_DIALOG1), MAKEINTRESOURCEA(5));213if (!dialog)214{215printf("Error finding wait for debugger dialog. Error %lu.\n", ::GetLastError());216return;217}218219DLGTEMPLATE *dialogTemplate = reinterpret_cast<DLGTEMPLATE *>(::LoadResource(instance, dialog));220::DialogBoxIndirectA(instance, dialogTemplate, NULL, DebuggerWaitDialogProc);221}222# else223void WaitForDebugger(HINSTANCE instance) {}224# endif // defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)225} // namespace226227extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID)228{229switch (reason)230{231case DLL_PROCESS_ATTACH:232if (angle::GetEnvironmentVar("ANGLE_WAIT_FOR_DEBUGGER") == "1")233{234WaitForDebugger(instance);235}236return static_cast<BOOL>(egl::InitializeProcess());237238case DLL_THREAD_ATTACH:239return static_cast<BOOL>(egl::AllocateCurrentThread() != nullptr);240241case DLL_THREAD_DETACH:242egl::DeallocateCurrentThread();243break;244245case DLL_PROCESS_DETACH:246egl::TerminateProcess();247break;248}249250return TRUE;251}252#endif // defined(ANGLE_PLATFORM_WINDOWS) && !defined(ANGLE_STATIC)253254255