tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

global_state.h (7228B)


      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.h : Defines functions for querying the thread-local GL and EGL state.
      8 
      9 #ifndef LIBGLESV2_GLOBALSTATE_H_
     10 #define LIBGLESV2_GLOBALSTATE_H_
     11 
     12 #include "libANGLE/Context.h"
     13 #include "libANGLE/Debug.h"
     14 #include "libANGLE/Thread.h"
     15 #include "libANGLE/features.h"
     16 
     17 #if defined(ANGLE_PLATFORM_APPLE) || (ANGLE_PLATFORM_ANDROID)
     18 #    include "common/tls.h"
     19 #endif
     20 
     21 #include <mutex>
     22 
     23 namespace angle
     24 {
     25 using GlobalMutex = std::recursive_mutex;
     26 
     27 //  - TLS_SLOT_OPENGL and TLS_SLOT_OPENGL_API: These two aren't used by bionic
     28 //    itself, but allow the graphics code to access TLS directly rather than
     29 //    using the pthread API.
     30 //
     31 // Choose the TLS_SLOT_OPENGL TLS slot with the value that matches value in the header file in
     32 // bionic(tls_defines.h)
     33 constexpr size_t kAndroidOpenGLTlsSlot = 3;
     34 
     35 #if defined(ANGLE_PLATFORM_ANDROID)
     36 
     37 // The following ASM variant provides a much more performant store/retrieve interface
     38 // compared to those provided by the pthread library. These have been derived from code
     39 // in the bionic module of Android ->
     40 // https://cs.android.com/android/platform/superproject/+/master:bionic/libc/platform/bionic/tls.h;l=30
     41 
     42 #    if defined(__aarch64__)
     43 #        define ANGLE_ANDROID_GET_GL_TLS()                  \
     44            ({                                              \
     45                void **__val;                               \
     46                __asm__("mrs %0, tpidr_el0" : "=r"(__val)); \
     47                __val;                                      \
     48            })
     49 #    elif defined(__arm__)
     50 #        define ANGLE_ANDROID_GET_GL_TLS()                           \
     51            ({                                                       \
     52                void **__val;                                        \
     53                __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r"(__val)); \
     54                __val;                                               \
     55            })
     56 #    elif defined(__mips__)
     57 // On mips32r1, this goes via a kernel illegal instruction trap that's
     58 // optimized for v1
     59 #        define ANGLE_ANDROID_GET_GL_TLS()       \
     60            ({                                   \
     61                register void **__val asm("v1"); \
     62                __asm__(                         \
     63                    ".set    push\n"             \
     64                    ".set    mips32r2\n"         \
     65                    "rdhwr   %0,$29\n"           \
     66                    ".set    pop\n"              \
     67                    : "=r"(__val));              \
     68                __val;                           \
     69            })
     70 #    elif defined(__i386__)
     71 #        define ANGLE_ANDROID_GET_GL_TLS()                \
     72            ({                                            \
     73                void **__val;                             \
     74                __asm__("movl %%gs:0, %0" : "=r"(__val)); \
     75                __val;                                    \
     76            })
     77 #    elif defined(__x86_64__)
     78 #        define ANGLE_ANDROID_GET_GL_TLS()               \
     79            ({                                           \
     80                void **__val;                            \
     81                __asm__("mov %%fs:0, %0" : "=r"(__val)); \
     82                __val;                                   \
     83            })
     84 #    else
     85 #        error unsupported architecture
     86 #    endif
     87 
     88 #endif  // ANGLE_PLATFORM_ANDROID
     89 }  // namespace angle
     90 
     91 namespace egl
     92 {
     93 class Debug;
     94 class Thread;
     95 
     96 #if defined(ANGLE_PLATFORM_APPLE)
     97 extern Thread *GetCurrentThreadTLS();
     98 extern void SetCurrentThreadTLS(Thread *thread);
     99 #else
    100 extern thread_local Thread *gCurrentThread;
    101 #endif
    102 
    103 angle::GlobalMutex &GetGlobalMutex();
    104 angle::GlobalMutex &GetGlobalSurfaceMutex();
    105 gl::Context *GetGlobalLastContext();
    106 void SetGlobalLastContext(gl::Context *context);
    107 Thread *GetCurrentThread();
    108 Debug *GetDebug();
    109 
    110 // Sync the current context from Thread to global state.
    111 class [[nodiscard]] ScopedSyncCurrentContextFromThread
    112 {
    113  public:
    114    ScopedSyncCurrentContextFromThread(egl::Thread *thread);
    115    ~ScopedSyncCurrentContextFromThread();
    116 
    117  private:
    118    egl::Thread *const mThread;
    119 };
    120 
    121 }  // namespace egl
    122 
    123 #define ANGLE_GLOBAL_SURFACE_LOCK_VAR_NAME globalSurfaceMutexLock
    124 #define ANGLE_SCOPED_GLOBAL_SURFACE_LOCK()                                  \
    125    std::lock_guard<angle::GlobalMutex> ANGLE_GLOBAL_SURFACE_LOCK_VAR_NAME( \
    126        egl::GetGlobalSurfaceMutex())
    127 
    128 #define ANGLE_GLOBAL_LOCK_VAR_NAME globalMutexLock
    129 #define ANGLE_SCOPED_GLOBAL_LOCK() \
    130    std::lock_guard<angle::GlobalMutex> ANGLE_GLOBAL_LOCK_VAR_NAME(egl::GetGlobalMutex())
    131 
    132 namespace gl
    133 {
    134 ANGLE_INLINE Context *GetGlobalContext()
    135 {
    136 #if defined(ANGLE_USE_ANDROID_TLS_SLOT)
    137    // TODO: Replace this branch with a compile time flag (http://anglebug.com/4764)
    138    if (angle::gUseAndroidOpenGLTlsSlot)
    139    {
    140        return static_cast<gl::Context *>(ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot]);
    141    }
    142 #endif
    143 
    144 #if defined(ANGLE_PLATFORM_APPLE)
    145    egl::Thread *currentThread = egl::GetCurrentThreadTLS();
    146 #else
    147    egl::Thread *currentThread = egl::gCurrentThread;
    148 #endif
    149    ASSERT(currentThread);
    150    return currentThread->getContext();
    151 }
    152 
    153 ANGLE_INLINE Context *GetValidGlobalContext()
    154 {
    155 #if defined(ANGLE_USE_ANDROID_TLS_SLOT)
    156    // TODO: Replace this branch with a compile time flag (http://anglebug.com/4764)
    157    if (angle::gUseAndroidOpenGLTlsSlot)
    158    {
    159        Context *context =
    160            static_cast<gl::Context *>(ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot]);
    161        if (context && !context->isContextLost())
    162        {
    163            return context;
    164        }
    165    }
    166 #endif
    167 
    168 #if defined(ANGLE_PLATFORM_APPLE)
    169    return GetCurrentValidContextTLS();
    170 #else
    171    return gCurrentValidContext;
    172 #endif
    173 }
    174 
    175 // Generate a context lost error on the context if it is non-null and lost.
    176 void GenerateContextLostErrorOnContext(Context *context);
    177 void GenerateContextLostErrorOnCurrentGlobalContext();
    178 
    179 #if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
    180 // TODO(b/177574181): This should be handled in a backend-specific way.
    181 // if previous context different from current context, dirty all state
    182 static ANGLE_INLINE void DirtyContextIfNeeded(Context *context)
    183 {
    184    if (context && context != egl::GetGlobalLastContext())
    185    {
    186        context->dirtyAllState();
    187        SetGlobalLastContext(context);
    188    }
    189 }
    190 
    191 #endif
    192 
    193 #if !defined(ANGLE_ENABLE_SHARE_CONTEXT_LOCK)
    194 #    define SCOPED_SHARE_CONTEXT_LOCK(context)
    195 #else
    196 ANGLE_INLINE std::unique_lock<angle::GlobalMutex> GetContextLock(Context *context)
    197 {
    198 #    if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
    199    auto lock = std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex());
    200 
    201    DirtyContextIfNeeded(context);
    202    return lock;
    203 #    else
    204    return context->isShared() ? std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex())
    205                               : std::unique_lock<angle::GlobalMutex>();
    206 #    endif
    207 }
    208 
    209 #    define SCOPED_SHARE_CONTEXT_LOCK(context) \
    210        std::unique_lock<angle::GlobalMutex> shareContextLock = GetContextLock(context)
    211 #endif
    212 
    213 }  // namespace gl
    214 
    215 #endif  // LIBGLESV2_GLOBALSTATE_H_