// // Copyright 2014 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. //
// global_state.cpp : Implements functions for querying the thread-local GL and EGL state.
#include <atomic> #ifdefined(ANGLE_PLATFORM_APPLE) # include <dispatch/dispatch.h> #endif
namespace egl
{
namespace
{
ANGLE_REQUIRE_CONSTANT_INIT std::atomic<angle::GlobalMutex *> g_Mutex{};
static_assert(std::is_trivially_destructible<decltype(g_Mutex)>::value, "global mutex is not trivially destructible");
ANGLE_REQUIRE_CONSTANT_INIT std::atomic<angle::GlobalMutex *> g_SurfaceMutex{};
static_assert(std::is_trivially_destructible<decltype(g_SurfaceMutex)>::value, "global mutex is not trivially destructible");
ANGLE_REQUIRE_CONSTANT_INIT gl::Context *g_LastContext(nullptr);
static_assert(std::is_trivially_destructible<decltype(g_LastContext)>::value, "global last context is not trivially destructible");
// Called only on Android platform
[[maybe_unused]] void ThreadCleanupCallback(void *ptr)
{
ANGLE_SCOPED_GLOBAL_LOCK();
angle::PthreadKeyDestructorCallback(ptr);
}
#ifdefined(ANGLE_PLATFORM_APPLE) // TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause // excessive memory use. Temporarily avoid it by using pthread's thread // local storage instead. // https://bugs.webkit.org/show_bug.cgi?id=228240
// This function causes an MSAN false positive, which is muted. See https://crbug.com/1211047 // It also causes a flaky false positive in TSAN. http://crbug.com/1223970
ANGLE_NO_SANITIZE_MEMORY ANGLE_NO_SANITIZE_THREAD Thread *GetCurrentThread()
{ #ifdefined(ANGLE_PLATFORM_APPLE)
Thread *current = GetCurrentThreadTLS(); #else
Thread *current = gCurrentThread; #endif return (current ? current : AllocateCurrentThread());
}
void GenerateContextLostErrorOnCurrentGlobalContext()
{ // If the client starts issuing GL calls before ANGLE has had a chance to initialize, // GenerateContextLostErrorOnCurrentGlobalContext can be called before AllocateCurrentThread has // had a chance to run. Calling GetCurrentThread() ensures that TLS thread state is set up.
egl::GetCurrentThread();
void DeallocateGlobalMutex(std::atomic<angle::GlobalMutex *> &mutex)
{
angle::GlobalMutex *toDelete = mutex.exchange(nullptr);
if (!mutex) return;
{ // Wait for toDelete to become released by other threads before deleting.
std::lock_guard<angle::GlobalMutex> lock(*toDelete);
}
SafeDelete(toDelete);
}
namespace
{ // The following WaitForDebugger code is based on SwiftShader. See: // https://cs.chromium.org/chromium/src/third_party/swiftshader/src/Vulkan/main.cpp # if defined(ANGLE_ENABLE_ASSERTS) && !defined(ANGLE_ENABLE_WINDOWS_UWP)
INT_PTR CALLBACK DebuggerWaitDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
RECT rect;
switch (uMsg)
{ case WM_INITDIALOG:
::GetWindowRect(GetDesktopWindow(), &rect);
::SetWindowPos(hwnd, HWND_TOP, rect.right / 2, rect.bottom / 2, 0, 0, SWP_NOSIZE);
::SetTimer(hwnd, 1, 100, NULL); returnTRUE; case WM_COMMAND:
if (LOWORD(wParam) == IDCANCEL)
{
::EndDialog(hwnd, 0);
} break; case WM_TIMER:
if (angle::IsDebuggerAttached())
{
::EndDialog(hwnd, 0);
}
}
return FALSE;
}
void WaitForDebugger(HINSTANCE instance)
{
if (angle::IsDebuggerAttached()) return;
HRSRC dialog = ::FindResourceA(instance, MAKEINTRESOURCEA(IDD_DIALOG1), MAKEINTRESOURCEA(5));
if (!dialog)
{
printf("Error finding wait for debugger dialog. Error %lu.\n", ::GetLastError()); return;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.