Path: blob/main_old/src/libGLESv2/global_state.h
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.h : Defines functions for querying the thread-local GL and EGL state.78#ifndef LIBGLESV2_GLOBALSTATE_H_9#define LIBGLESV2_GLOBALSTATE_H_1011#include "libANGLE/Context.h"12#include "libANGLE/Debug.h"13#include "libANGLE/Thread.h"14#include "libANGLE/features.h"1516#include <mutex>1718namespace angle19{20using GlobalMutex = std::recursive_mutex;2122// - TLS_SLOT_OPENGL and TLS_SLOT_OPENGL_API: These two aren't used by bionic23// itself, but allow the graphics code to access TLS directly rather than24// using the pthread API.25//26// Choose the TLS_SLOT_OPENGL TLS slot with the value that matches value in the header file in27// bionic(tls_defines.h)28constexpr size_t kAndroidOpenGLTlsSlot = 3;2930#if defined(ANGLE_PLATFORM_ANDROID)3132// The following ASM variant provides a much more performant store/retrieve interface33// compared to those provided by the pthread library. These have been derived from code34// in the bionic module of Android ->35// https://cs.android.com/android/platform/superproject/+/master:bionic/libc/platform/bionic/tls.h;l=303637# if defined(__aarch64__)38# define ANGLE_ANDROID_GET_GL_TLS() \39({ \40void **__val; \41__asm__("mrs %0, tpidr_el0" : "=r"(__val)); \42__val; \43})44# elif defined(__arm__)45# define ANGLE_ANDROID_GET_GL_TLS() \46({ \47void **__val; \48__asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__val)); \49__val; \50})51# elif defined(__mips__)52// On mips32r1, this goes via a kernel illegal instruction trap that's53// optimized for v154# define ANGLE_ANDROID_GET_GL_TLS() \55({ \56register void **__val asm("v1"); \57__asm__( \58".set push\n" \59".set mips32r2\n" \60"rdhwr %0,$29\n" \61".set pop\n" \62: "=r"(__val)); \63__val; \64})65# elif defined(__i386__)66# define ANGLE_ANDROID_GET_GL_TLS() \67({ \68void **__val; \69__asm__("movl %%gs:0, %0" : "=r"(__val)); \70__val; \71})72# elif defined(__x86_64__)73# define ANGLE_ANDROID_GET_GL_TLS() \74({ \75void **__val; \76__asm__("mov %%fs:0, %0" : "=r"(__val)); \77__val; \78})79# else80# error unsupported architecture81# endif8283#endif // ANGLE_PLATFORM_ANDROID84} // namespace angle8586namespace egl87{88class Debug;89class Thread;9091extern thread_local Thread *gCurrentThread;9293angle::GlobalMutex &GetGlobalMutex();94gl::Context *GetGlobalLastContext();95void SetGlobalLastContext(gl::Context *context);96Thread *GetCurrentThread();97Debug *GetDebug();9899// Sync the current context from Thread to global state.100class ScopedSyncCurrentContextFromThread101{102public:103ScopedSyncCurrentContextFromThread(egl::Thread *thread);104~ScopedSyncCurrentContextFromThread();105106private:107egl::Thread *const mThread;108};109110} // namespace egl111112#define ANGLE_SCOPED_GLOBAL_LOCK() \113std::lock_guard<angle::GlobalMutex> globalMutexLock(egl::GetGlobalMutex())114115namespace gl116{117ANGLE_INLINE Context *GetGlobalContext()118{119#if defined(ANGLE_PLATFORM_ANDROID)120// TODO: Replace this branch with a compile time flag (http://anglebug.com/4764)121if (angle::gUseAndroidOpenGLTlsSlot)122{123return static_cast<gl::Context *>(ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot]);124}125#endif126127ASSERT(egl::gCurrentThread);128return egl::gCurrentThread->getContext();129}130131ANGLE_INLINE Context *GetValidGlobalContext()132{133#if defined(ANGLE_PLATFORM_ANDROID)134// TODO: Replace this branch with a compile time flag (http://anglebug.com/4764)135if (angle::gUseAndroidOpenGLTlsSlot)136{137Context *context =138static_cast<gl::Context *>(ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot]);139if (context && !context->isContextLost())140{141return context;142}143}144#endif145146return gCurrentValidContext;147}148149// Generate a context lost error on the context if it is non-null and lost.150void GenerateContextLostErrorOnContext(Context *context);151void GenerateContextLostErrorOnCurrentGlobalContext();152153#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)154// TODO(b/177574181): This should be handled in a backend-specific way.155// if previous context different from current context, dirty all state156static ANGLE_INLINE void DirtyContextIfNeeded(Context *context)157{158if (context && context != egl::GetGlobalLastContext())159{160context->dirtyAllState();161SetGlobalLastContext(context);162}163}164165#endif166167ANGLE_INLINE std::unique_lock<angle::GlobalMutex> GetContextLock(Context *context)168{169#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)170auto lock = std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex());171172DirtyContextIfNeeded(context);173return lock;174#else175return context->isShared() ? std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex())176: std::unique_lock<angle::GlobalMutex>();177#endif178}179180} // namespace gl181182#endif // LIBGLESV2_GLOBALSTATE_H_183184185