Commit e7ca0aa2 by Doug Horn Committed by Commit Bot

Fix crash in multi-context D3D11 backend.

The crash occured due to a lack of marking a context dirty on eglMakeCurrent(), resulting in a situation where a thread B would call eglMakeCurrent() but before issuing additional GL calls, thread A would issue a draw command. Prior to this change, context state would only be marked dirty on gl calls. Test: dEQP-EGL.functional.sharing.gles2.multithread.* dEQP-EGL.functional.multithread.* dEQP-EGL.functional.render.multi_thread.* dEQP-EGL.functional.color_clears.multi_thread.* Bug: b/177602915 Change-Id: I765e0423002a373f94ea459b81b6e6f6942870d2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2646609Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Doug Horn <doughorn@google.com>
parent fdf441ce
...@@ -481,7 +481,6 @@ EGLBoolean MakeCurrent(Thread *thread, ...@@ -481,7 +481,6 @@ EGLBoolean MakeCurrent(Thread *thread,
ANGLE_EGL_TRY_RETURN( ANGLE_EGL_TRY_RETURN(
thread, display->makeCurrent(previousContext, drawSurface, readSurface, context), thread, display->makeCurrent(previousContext, drawSurface, readSurface, context),
"eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE); "eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
SetContextCurrent(thread, context); SetContextCurrent(thread, context);
} }
......
...@@ -99,7 +99,11 @@ void SetContextCurrent(Thread *thread, gl::Context *context) ...@@ -99,7 +99,11 @@ void SetContextCurrent(Thread *thread, gl::Context *context)
gCurrentThread->setCurrent(context); gCurrentThread->setCurrent(context);
SetContextToAndroidOpenGLTLSSlot(context); SetContextToAndroidOpenGLTLSSlot(context);
gl::gCurrentValidContext = context; gl::gCurrentValidContext = context;
#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
DirtyContextIfNeeded(context);
#endif
} }
} // namespace egl } // namespace egl
namespace gl namespace gl
......
...@@ -140,17 +140,26 @@ ANGLE_INLINE Context *GetValidGlobalContext() ...@@ -140,17 +140,26 @@ ANGLE_INLINE Context *GetValidGlobalContext()
void GenerateContextLostErrorOnContext(Context *context); void GenerateContextLostErrorOnContext(Context *context);
void GenerateContextLostErrorOnCurrentGlobalContext(); void GenerateContextLostErrorOnCurrentGlobalContext();
ANGLE_INLINE std::unique_lock<angle::GlobalMutex> GetContextLock(Context *context)
{
#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL) #if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
auto lock = std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex()); // TODO(b/177574181): This should be handled in a backend-specific way.
// TODO(b/177574181): This should be handled in a backend-specific way. // if previous context different from current context, dirty all state
// if previous context different from current context, dirty all state static ANGLE_INLINE void DirtyContextIfNeeded(Context *context)
if (context != egl::GetGlobalLastContext()) {
if (context && context != egl::GetGlobalLastContext())
{ {
context->dirtyAllState(); context->dirtyAllState();
SetGlobalLastContext(context); SetGlobalLastContext(context);
} }
}
#endif
ANGLE_INLINE std::unique_lock<angle::GlobalMutex> GetContextLock(Context *context)
{
#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
auto lock = std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex());
DirtyContextIfNeeded(context);
return lock; return lock;
#else #else
return context->isShared() ? std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex()) return context->isShared() ? std::unique_lock<angle::GlobalMutex>(egl::GetGlobalMutex())
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment