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,
ANGLE_EGL_TRY_RETURN(
thread, display->makeCurrent(previousContext, drawSurface, readSurface, context),
"eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
SetContextCurrent(thread, context);
}
......
......@@ -99,7 +99,11 @@ void SetContextCurrent(Thread *thread, gl::Context *context)
gCurrentThread->setCurrent(context);
SetContextToAndroidOpenGLTLSSlot(context);
gl::gCurrentValidContext = context;
#if defined(ANGLE_FORCE_CONTEXT_CHECK_EVERY_CALL)
DirtyContextIfNeeded(context);
#endif
}
} // namespace egl
namespace gl
......
......@@ -140,17 +140,26 @@ ANGLE_INLINE Context *GetValidGlobalContext()
void GenerateContextLostErrorOnContext(Context *context);
void GenerateContextLostErrorOnCurrentGlobalContext();
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());
// TODO(b/177574181): This should be handled in a backend-specific way.
// if previous context different from current context, dirty all state
if (context != egl::GetGlobalLastContext())
// TODO(b/177574181): This should be handled in a backend-specific way.
// if previous context different from current context, dirty all state
static ANGLE_INLINE void DirtyContextIfNeeded(Context *context)
{
if (context && context != egl::GetGlobalLastContext())
{
context->dirtyAllState();
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;
#else
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