зеркало из https://github.com/AvaloniaUI/angle.git
Fix racy global in gl::Compiler.
We introduce a new Display Global Mutex in egl::Display that can guard access to gActiveCompilers in Compiler.cpp. Was detected by running MultithreadingTest against TSAN. Bug: b/168744561 Change-Id: I97866b60a173f60899cd0406fe0f71000035c0cf Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2415181 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Courtney Goeltzenleuchter <courtneygo@google.com> Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
This commit is contained in:
Родитель
1c79e9ea29
Коммит
f2749096ea
|
@ -9,6 +9,8 @@
|
|||
#include "libANGLE/Compiler.h"
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "libANGLE/Context.h"
|
||||
#include "libANGLE/Display.h"
|
||||
#include "libANGLE/State.h"
|
||||
#include "libANGLE/renderer/CompilerImpl.h"
|
||||
#include "libANGLE/renderer/GLImplFactory.h"
|
||||
|
@ -56,7 +58,7 @@ ShShaderSpec SelectShaderSpec(GLint majorVersion,
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state)
|
||||
Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state, egl::Display *display)
|
||||
: mImplementation(implFactory->createCompiler()),
|
||||
mSpec(SelectShaderSpec(state.getClientMajorVersion(),
|
||||
state.getClientMinorVersion(),
|
||||
|
@ -72,11 +74,14 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state)
|
|||
const gl::Caps &caps = state.getCaps();
|
||||
const gl::Extensions &extensions = state.getExtensions();
|
||||
|
||||
if (gActiveCompilers == 0)
|
||||
{
|
||||
sh::Initialize();
|
||||
std::lock_guard<std::mutex> lock(display->getDisplayGlobalMutex());
|
||||
if (gActiveCompilers == 0)
|
||||
{
|
||||
sh::Initialize();
|
||||
}
|
||||
++gActiveCompilers;
|
||||
}
|
||||
++gActiveCompilers;
|
||||
|
||||
sh::InitBuiltInResources(&mResources);
|
||||
mResources.MaxVertexAttribs = caps.maxVertexAttributes;
|
||||
|
@ -211,8 +216,11 @@ Compiler::Compiler(rx::GLImplFactory *implFactory, const State &state)
|
|||
mResources.SubPixelBits = static_cast<int>(caps.subPixelBits);
|
||||
}
|
||||
|
||||
Compiler::~Compiler()
|
||||
Compiler::~Compiler() = default;
|
||||
|
||||
void Compiler::onDestroy(const Context *context)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(context->getDisplay()->getDisplayGlobalMutex());
|
||||
for (auto &pool : mPools)
|
||||
{
|
||||
for (ShCompilerInstance &instance : pool)
|
||||
|
|
|
@ -31,7 +31,9 @@ class State;
|
|||
class Compiler final : public RefCountObjectNoID
|
||||
{
|
||||
public:
|
||||
Compiler(rx::GLImplFactory *implFactory, const State &data);
|
||||
Compiler(rx::GLImplFactory *implFactory, const State &data, egl::Display *display);
|
||||
|
||||
void onDestroy(const Context *context) override;
|
||||
|
||||
ShCompilerInstance getInstance(ShaderType shaderType);
|
||||
void putInstance(ShCompilerInstance &&instance);
|
||||
|
|
|
@ -1367,7 +1367,7 @@ Compiler *Context::getCompiler() const
|
|||
{
|
||||
if (mCompiler.get() == nullptr)
|
||||
{
|
||||
mCompiler.set(this, new Compiler(mImplementation.get(), mState));
|
||||
mCompiler.set(this, new Compiler(mImplementation.get(), mState, mDisplay));
|
||||
}
|
||||
return mCompiler.get();
|
||||
}
|
||||
|
|
|
@ -255,6 +255,8 @@ class Display final : public LabeledObject,
|
|||
|
||||
egl::Error handleGPUSwitch();
|
||||
|
||||
std::mutex &getDisplayGlobalMutex() { return mDisplayGlobalMutex; }
|
||||
|
||||
private:
|
||||
Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice);
|
||||
|
||||
|
@ -323,6 +325,8 @@ class Display final : public LabeledObject,
|
|||
std::mutex mScratchBufferMutex;
|
||||
std::vector<angle::ScratchBuffer> mScratchBuffers;
|
||||
std::vector<angle::ScratchBuffer> mZeroFilledBuffers;
|
||||
|
||||
std::mutex mDisplayGlobalMutex;
|
||||
};
|
||||
|
||||
} // namespace egl
|
||||
|
|
Загрузка…
Ссылка в новой задаче