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.h : Defines functions for querying the thread-local GL and EGL state.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #ifndef LIBGLESV2_GLOBALSTATE_H_
10*8975f5c5SAndroid Build Coastguard Worker #define LIBGLESV2_GLOBALSTATE_H_
11*8975f5c5SAndroid Build Coastguard Worker
12*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Debug.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Display.h"
15*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/GlobalMutex.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Thread.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/features.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/validationEGL.h"
19*8975f5c5SAndroid Build Coastguard Worker
20*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE) || (ANGLE_PLATFORM_ANDROID) || defined(ANGLE_USE_ANDROID_TLS_SLOT)
21*8975f5c5SAndroid Build Coastguard Worker # include "common/tls.h"
22*8975f5c5SAndroid Build Coastguard Worker #endif
23*8975f5c5SAndroid Build Coastguard Worker
24*8975f5c5SAndroid Build Coastguard Worker #include <mutex>
25*8975f5c5SAndroid Build Coastguard Worker
26*8975f5c5SAndroid Build Coastguard Worker namespace egl
27*8975f5c5SAndroid Build Coastguard Worker {
28*8975f5c5SAndroid Build Coastguard Worker class Debug;
29*8975f5c5SAndroid Build Coastguard Worker class Thread;
30*8975f5c5SAndroid Build Coastguard Worker
31*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE) || defined(ANGLE_USE_STATIC_THREAD_LOCAL_VARIABLES)
32*8975f5c5SAndroid Build Coastguard Worker extern Thread *GetCurrentThreadTLS();
33*8975f5c5SAndroid Build Coastguard Worker extern void SetCurrentThreadTLS(Thread *thread);
34*8975f5c5SAndroid Build Coastguard Worker #else
35*8975f5c5SAndroid Build Coastguard Worker extern thread_local Thread *gCurrentThread;
36*8975f5c5SAndroid Build Coastguard Worker #endif
37*8975f5c5SAndroid Build Coastguard Worker
38*8975f5c5SAndroid Build Coastguard Worker gl::Context *GetGlobalLastContext();
39*8975f5c5SAndroid Build Coastguard Worker void SetGlobalLastContext(gl::Context *context);
40*8975f5c5SAndroid Build Coastguard Worker Thread *GetCurrentThread();
41*8975f5c5SAndroid Build Coastguard Worker Debug *GetDebug();
42*8975f5c5SAndroid Build Coastguard Worker
43*8975f5c5SAndroid Build Coastguard Worker void SetEGLValidationEnabled(bool enabled);
44*8975f5c5SAndroid Build Coastguard Worker bool IsEGLValidationEnabled();
45*8975f5c5SAndroid Build Coastguard Worker
46*8975f5c5SAndroid Build Coastguard Worker // Sync the current context from Thread to global state.
47*8975f5c5SAndroid Build Coastguard Worker class [[nodiscard]] ScopedSyncCurrentContextFromThread
48*8975f5c5SAndroid Build Coastguard Worker {
49*8975f5c5SAndroid Build Coastguard Worker public:
50*8975f5c5SAndroid Build Coastguard Worker ScopedSyncCurrentContextFromThread(egl::Thread *thread);
51*8975f5c5SAndroid Build Coastguard Worker ~ScopedSyncCurrentContextFromThread();
52*8975f5c5SAndroid Build Coastguard Worker
53*8975f5c5SAndroid Build Coastguard Worker private:
54*8975f5c5SAndroid Build Coastguard Worker egl::Thread *const mThread;
55*8975f5c5SAndroid Build Coastguard Worker };
56*8975f5c5SAndroid Build Coastguard Worker
57*8975f5c5SAndroid Build Coastguard Worker // Tries to lock "ContextMutex" of the Context current to the "thread".
TryLockCurrentContext(Thread * thread)58*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE ScopedContextMutexLock TryLockCurrentContext(Thread *thread)
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker ASSERT(kIsContextMutexEnabled);
61*8975f5c5SAndroid Build Coastguard Worker gl::Context *context = thread->getContext();
62*8975f5c5SAndroid Build Coastguard Worker return context != nullptr ? ScopedContextMutexLock(context->getContextMutex())
63*8975f5c5SAndroid Build Coastguard Worker : ScopedContextMutexLock();
64*8975f5c5SAndroid Build Coastguard Worker }
65*8975f5c5SAndroid Build Coastguard Worker
66*8975f5c5SAndroid Build Coastguard Worker // Tries to lock "ContextMutex" of the Context with "contextID" if it is valid.
TryLockContext(Display * display,gl::ContextID contextID)67*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE ScopedContextMutexLock TryLockContext(Display *display, gl::ContextID contextID)
68*8975f5c5SAndroid Build Coastguard Worker {
69*8975f5c5SAndroid Build Coastguard Worker ASSERT(kIsContextMutexEnabled);
70*8975f5c5SAndroid Build Coastguard Worker gl::Context *context = GetContextIfValid(display, contextID);
71*8975f5c5SAndroid Build Coastguard Worker return context != nullptr ? ScopedContextMutexLock(context->getContextMutex())
72*8975f5c5SAndroid Build Coastguard Worker : ScopedContextMutexLock();
73*8975f5c5SAndroid Build Coastguard Worker }
74*8975f5c5SAndroid Build Coastguard Worker
75*8975f5c5SAndroid Build Coastguard Worker // Locks "ContextMutex" of the "context" and then tries to merge it with the "ContextMutex" of the
76*8975f5c5SAndroid Build Coastguard Worker // Image with "imageID" if it is valid.
LockAndTryMergeContextMutexes(gl::Context * context,ImageID imageID)77*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE ScopedContextMutexLock LockAndTryMergeContextMutexes(gl::Context *context,
78*8975f5c5SAndroid Build Coastguard Worker ImageID imageID)
79*8975f5c5SAndroid Build Coastguard Worker {
80*8975f5c5SAndroid Build Coastguard Worker ASSERT(kIsContextMutexEnabled);
81*8975f5c5SAndroid Build Coastguard Worker ASSERT(context->getDisplay() != nullptr);
82*8975f5c5SAndroid Build Coastguard Worker ScopedContextMutexLock lock(context->getContextMutex());
83*8975f5c5SAndroid Build Coastguard Worker const Image *image = context->getDisplay()->getImage(imageID);
84*8975f5c5SAndroid Build Coastguard Worker if (image != nullptr)
85*8975f5c5SAndroid Build Coastguard Worker {
86*8975f5c5SAndroid Build Coastguard Worker ContextMutex *imageMutex = image->getContextMutex();
87*8975f5c5SAndroid Build Coastguard Worker if (imageMutex != nullptr)
88*8975f5c5SAndroid Build Coastguard Worker {
89*8975f5c5SAndroid Build Coastguard Worker ContextMutex::Merge(&context->getContextMutex(), imageMutex);
90*8975f5c5SAndroid Build Coastguard Worker }
91*8975f5c5SAndroid Build Coastguard Worker }
92*8975f5c5SAndroid Build Coastguard Worker return lock;
93*8975f5c5SAndroid Build Coastguard Worker }
94*8975f5c5SAndroid Build Coastguard Worker
95*8975f5c5SAndroid Build Coastguard Worker #if !defined(ANGLE_ENABLE_CONTEXT_MUTEX)
96*8975f5c5SAndroid Build Coastguard Worker # define ANGLE_EGL_SCOPED_CONTEXT_LOCK(EP, THREAD, ...)
97*8975f5c5SAndroid Build Coastguard Worker #else
98*8975f5c5SAndroid Build Coastguard Worker # define ANGLE_EGL_SCOPED_CONTEXT_LOCK(EP, THREAD, ...) \
99*8975f5c5SAndroid Build Coastguard Worker egl::ScopedContextMutexLock shareContextLock = GetContextLock_##EP(THREAD, ##__VA_ARGS__)
100*8975f5c5SAndroid Build Coastguard Worker #endif
101*8975f5c5SAndroid Build Coastguard Worker
102*8975f5c5SAndroid Build Coastguard Worker } // namespace egl
103*8975f5c5SAndroid Build Coastguard Worker
104*8975f5c5SAndroid Build Coastguard Worker #define ANGLE_SCOPED_GLOBAL_LOCK() egl::ScopedGlobalEGLMutexLock globalMutexLock
105*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_CAPTURE_ENABLED
106*8975f5c5SAndroid Build Coastguard Worker # define ANGLE_SCOPED_GLOBAL_EGL_AND_EGL_SYNC_LOCK() \
107*8975f5c5SAndroid Build Coastguard Worker egl::ScopedGlobalEGLMutexLock globalMutexLock
108*8975f5c5SAndroid Build Coastguard Worker #else
109*8975f5c5SAndroid Build Coastguard Worker # define ANGLE_SCOPED_GLOBAL_EGL_AND_EGL_SYNC_LOCK() \
110*8975f5c5SAndroid Build Coastguard Worker egl::ScopedGlobalEGLMutexLock globalMutexLock; \
111*8975f5c5SAndroid Build Coastguard Worker egl::ScopedGlobalEGLSyncObjectMutexLock globalEGLSyncObjectMutexLock
112*8975f5c5SAndroid Build Coastguard Worker #endif
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Worker #if ANGLE_CAPTURE_ENABLED
115*8975f5c5SAndroid Build Coastguard Worker # define ANGLE_SCOPED_GLOBAL_EGL_SYNC_LOCK() egl::ScopedGlobalEGLMutexLock globalMutexLock
116*8975f5c5SAndroid Build Coastguard Worker #else
117*8975f5c5SAndroid Build Coastguard Worker # define ANGLE_SCOPED_GLOBAL_EGL_SYNC_LOCK() \
118*8975f5c5SAndroid Build Coastguard Worker egl::ScopedGlobalEGLSyncObjectMutexLock globalEGLSyncObjectMutexLock
119*8975f5c5SAndroid Build Coastguard Worker #endif
120*8975f5c5SAndroid Build Coastguard Worker
121*8975f5c5SAndroid Build Coastguard Worker namespace gl
122*8975f5c5SAndroid Build Coastguard Worker {
GetGlobalContext()123*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE Context *GetGlobalContext()
124*8975f5c5SAndroid Build Coastguard Worker {
125*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_PLATFORM_APPLE) || defined(ANGLE_USE_STATIC_THREAD_LOCAL_VARIABLES)
126*8975f5c5SAndroid Build Coastguard Worker egl::Thread *currentThread = egl::GetCurrentThreadTLS();
127*8975f5c5SAndroid Build Coastguard Worker #else
128*8975f5c5SAndroid Build Coastguard Worker egl::Thread *currentThread = egl::gCurrentThread;
129*8975f5c5SAndroid Build Coastguard Worker #endif
130*8975f5c5SAndroid Build Coastguard Worker ASSERT(currentThread);
131*8975f5c5SAndroid Build Coastguard Worker return currentThread->getContext();
132*8975f5c5SAndroid Build Coastguard Worker }
133*8975f5c5SAndroid Build Coastguard Worker
GetValidGlobalContext()134*8975f5c5SAndroid Build Coastguard Worker ANGLE_INLINE Context *GetValidGlobalContext()
135*8975f5c5SAndroid Build Coastguard Worker {
136*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_USE_ANDROID_TLS_SLOT)
137*8975f5c5SAndroid Build Coastguard Worker // TODO: Replace this branch with a compile time flag (http://anglebug.com/42263361)
138*8975f5c5SAndroid Build Coastguard Worker if (angle::gUseAndroidOpenGLTlsSlot)
139*8975f5c5SAndroid Build Coastguard Worker {
140*8975f5c5SAndroid Build Coastguard Worker return static_cast<gl::Context *>(ANGLE_ANDROID_GET_GL_TLS()[angle::kAndroidOpenGLTlsSlot]);
141*8975f5c5SAndroid Build Coastguard Worker }
142*8975f5c5SAndroid Build Coastguard Worker #endif
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 return GetCurrentValidContextTLS();
146*8975f5c5SAndroid Build Coastguard Worker #else
147*8975f5c5SAndroid Build Coastguard Worker return gCurrentValidContext;
148*8975f5c5SAndroid Build Coastguard Worker #endif
149*8975f5c5SAndroid Build Coastguard Worker }
150*8975f5c5SAndroid Build Coastguard Worker
151*8975f5c5SAndroid Build Coastguard Worker // Generate a context lost error on the context if it is non-null and lost.
152*8975f5c5SAndroid Build Coastguard Worker void GenerateContextLostErrorOnContext(Context *context);
153*8975f5c5SAndroid Build Coastguard Worker void GenerateContextLostErrorOnCurrentGlobalContext();
154*8975f5c5SAndroid Build Coastguard Worker
155*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
156*8975f5c5SAndroid Build Coastguard Worker // TODO(b/177574181): This should be handled in a backend-specific way.
157*8975f5c5SAndroid Build Coastguard Worker // if previous context different from current context, dirty all state
DirtyContextIfNeeded(Context * context)158*8975f5c5SAndroid Build Coastguard Worker static ANGLE_INLINE void DirtyContextIfNeeded(Context *context)
159*8975f5c5SAndroid Build Coastguard Worker {
160*8975f5c5SAndroid Build Coastguard Worker if (context && context != egl::GetGlobalLastContext())
161*8975f5c5SAndroid Build Coastguard Worker {
162*8975f5c5SAndroid Build Coastguard Worker context->dirtyAllState();
163*8975f5c5SAndroid Build Coastguard Worker SetGlobalLastContext(context);
164*8975f5c5SAndroid Build Coastguard Worker }
165*8975f5c5SAndroid Build Coastguard Worker }
166*8975f5c5SAndroid Build Coastguard Worker
167*8975f5c5SAndroid Build Coastguard Worker #endif
168*8975f5c5SAndroid Build Coastguard Worker
169*8975f5c5SAndroid Build Coastguard Worker #if !defined(ANGLE_ENABLE_SHARE_CONTEXT_LOCK)
170*8975f5c5SAndroid Build Coastguard Worker # define SCOPED_SHARE_CONTEXT_LOCK(context)
171*8975f5c5SAndroid Build Coastguard Worker # define SCOPED_EGL_IMAGE_SHARE_CONTEXT_LOCK(context, imageID) ANGLE_SCOPED_GLOBAL_LOCK()
172*8975f5c5SAndroid Build Coastguard Worker #else
173*8975f5c5SAndroid Build Coastguard Worker # if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
174*8975f5c5SAndroid Build Coastguard Worker # define SCOPED_SHARE_CONTEXT_LOCK(context) \
175*8975f5c5SAndroid Build Coastguard Worker egl::ScopedGlobalEGLMutexLock shareContextLock; \
176*8975f5c5SAndroid Build Coastguard Worker DirtyContextIfNeeded(context)
177*8975f5c5SAndroid Build Coastguard Worker # define SCOPED_EGL_IMAGE_SHARE_CONTEXT_LOCK(context, imageID) \
178*8975f5c5SAndroid Build Coastguard Worker SCOPED_SHARE_CONTEXT_LOCK(context)
179*8975f5c5SAndroid Build Coastguard Worker # elif !defined(ANGLE_ENABLE_CONTEXT_MUTEX)
180*8975f5c5SAndroid Build Coastguard Worker # define SCOPED_SHARE_CONTEXT_LOCK(context) \
181*8975f5c5SAndroid Build Coastguard Worker egl::ScopedOptionalGlobalMutexLock shareContextLock(context->isShared())
182*8975f5c5SAndroid Build Coastguard Worker # define SCOPED_EGL_IMAGE_SHARE_CONTEXT_LOCK(context, imageID) ANGLE_SCOPED_GLOBAL_LOCK()
183*8975f5c5SAndroid Build Coastguard Worker # else
184*8975f5c5SAndroid Build Coastguard Worker # define SCOPED_SHARE_CONTEXT_LOCK(context) \
185*8975f5c5SAndroid Build Coastguard Worker egl::ScopedContextMutexLock shareContextLock(context->getContextMutex())
186*8975f5c5SAndroid Build Coastguard Worker # define SCOPED_EGL_IMAGE_SHARE_CONTEXT_LOCK(context, imageID) \
187*8975f5c5SAndroid Build Coastguard Worker ANGLE_SCOPED_GLOBAL_LOCK(); \
188*8975f5c5SAndroid Build Coastguard Worker egl::ScopedContextMutexLock shareContextLock = \
189*8975f5c5SAndroid Build Coastguard Worker egl::LockAndTryMergeContextMutexes(context, imageID)
190*8975f5c5SAndroid Build Coastguard Worker # endif
191*8975f5c5SAndroid Build Coastguard Worker #endif
192*8975f5c5SAndroid Build Coastguard Worker
193*8975f5c5SAndroid Build Coastguard Worker } // namespace gl
194*8975f5c5SAndroid Build Coastguard Worker
195*8975f5c5SAndroid Build Coastguard Worker #endif // LIBGLESV2_GLOBALSTATE_H_
196