Compile GLSL in a critical section
Our copy of glslang is not thread safe, so we need to ensure a mutex is
held during GLSL compilation. With shared contexts this was already the
case because we lock a mutex belonging to the shared resource manager
(through es2::getContext()), but using independent contexts in multiple
threads was unsafe.
Use of glReleaseShaderCompiler() was also unsafe, even with shared
contexts, because no lock was taken.
Bug: b/137828018
Change-Id: I90028035868f95c5a121777aee05c2128a2f8180
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/34488
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/libGLESv2/Shader.cpp b/src/OpenGL/libGLESv2/Shader.cpp
index 269d884..db5efeb 100644
--- a/src/OpenGL/libGLESv2/Shader.cpp
+++ b/src/OpenGL/libGLESv2/Shader.cpp
@@ -26,6 +26,7 @@
namespace es2
{
+std::mutex Shader::mutex;
bool Shader::compilerInitialized = false;
Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
@@ -206,6 +207,9 @@
void Shader::compile()
{
+ // Our version of glslang is not thread safe.
+ std::lock_guard<std::mutex> lock(mutex);
+
clear();
createShader();
@@ -295,6 +299,9 @@
void Shader::releaseCompiler()
{
+ // Our version of glslang is not thread safe.
+ std::lock_guard<std::mutex> lock(mutex);
+
FreeCompilerGlobals();
compilerInitialized = false;
}
diff --git a/src/OpenGL/libGLESv2/Shader.h b/src/OpenGL/libGLESv2/Shader.h
index 63d50ae..32cbaf6 100644
--- a/src/OpenGL/libGLESv2/Shader.h
+++ b/src/OpenGL/libGLESv2/Shader.h
@@ -28,6 +28,7 @@
#include <string>
#include <list>
+#include <mutex>
#include <vector>
namespace glsl
@@ -69,7 +70,9 @@
static void releaseCompiler();
protected:
+ static std::mutex mutex;
static bool compilerInitialized;
+
TranslatorASM *createCompiler(GLenum shaderType);
void clear();