Commit 108f3e10 by Chris Forbes

Fix GL resource access thread safety

Add resource manager lock, and ContextPtr to automatically take it Affects: Everything, dEQP-EGL.functional.sharing.gles2.multithread.* Bug: b/112184433 Change-Id: Ifdc5b18c738f92bbab08217f672a8ed6093e1672 Reviewed-on: https://swiftshader-review.googlesource.com/20388Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarChris Forbes <chrisforbes@google.com>
parent 787e3d5b
......@@ -699,6 +699,7 @@ public:
Device *getDevice();
const GLubyte *getExtensions(GLuint index, GLuint *numExt = nullptr) const;
sw::MutexLock *getResourceLock() { return mResourceManager->getLock(); }
private:
~Context() override;
......@@ -769,6 +770,26 @@ private:
Device *device;
ResourceManager *mResourceManager;
};
// ptr to a context, which also holds the context's resource manager's lock.
class ContextPtr {
public:
explicit ContextPtr(Context *context) : ptr(context)
{
if (ptr) ptr->getResourceLock()->lock();
}
~ContextPtr() {
if (ptr) ptr->getResourceLock()->unlock();
}
Context *operator ->() { return ptr; }
operator bool() const { return ptr != nullptr; }
private:
Context *ptr;
};
}
#endif // INCLUDE_CONTEXT_H_
......@@ -65,7 +65,7 @@ Framebuffer::~Framebuffer()
Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level) const
{
Context *context = getContext();
Context *context = getContextLocked();
Renderbuffer *buffer = nullptr;
if(type == GL_NONE)
......
......@@ -19,6 +19,7 @@
#define LIBGLESV2_RESOURCEMANAGER_H_
#include "common/NameSpace.hpp"
#include "Common/MutexLock.hpp"
#include <GLES2/gl2.h>
......@@ -86,9 +87,11 @@ public:
void checkSamplerAllocation(GLuint sampler);
bool isSampler(GLuint sampler);
sw::MutexLock *getLock() { return &mMutex; }
private:
std::size_t mRefCount;
sw::MutexLock mMutex;
gl::NameSpace<Buffer> mBufferNameSpace;
gl::NameSpace<Program> mProgramNameSpace;
......
......@@ -75,7 +75,7 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
namespace es2
{
es2::Context *getContext()
Context *getContextLocked()
{
egl::Context *context = libEGL->clientGetCurrentContext();
......@@ -88,17 +88,23 @@ es2::Context *getContext()
return nullptr;
}
ContextPtr getContext()
{
return ContextPtr{getContextLocked()};
}
Device *getDevice()
{
Context *context = getContext();
Context *context = getContextLocked();
return context ? context->getDevice() : nullptr;
}
// Records an error code
// Assumed to already hold the context lock for the current context
void error(GLenum errorCode)
{
es2::Context *context = es2::getContext();
es2::Context *context = es2::getContextLocked();
if(context)
{
......
......@@ -30,7 +30,8 @@
namespace es2
{
Context *getContext();
Context *getContextLocked();
ContextPtr getContext();
Device *getDevice();
void error(GLenum errorCode);
......
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