Commit 3c8f6094 by Jonah Ryan-Davis Committed by Commit Bot

EGL: Add basic multithreading support

Adds first step to allowing multithreaded contexts: letting multiple threads use ANGLE as long as only one thread has a current context at a time. Bug: angleproject:4724 Bug: angleproject:4725 Change-Id: I4f606bdb15386cff9e3cb84d4120781e24e15fe4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2269864Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>
parent acbe145c
...@@ -278,6 +278,8 @@ void DisplayEGL::terminate() ...@@ -278,6 +278,8 @@ void DisplayEGL::terminate()
mRenderer.reset(); mRenderer.reset();
mCurrentNativeContexts.clear();
egl::Error result = mEGL->terminate(); egl::Error result = mEGL->terminate();
if (result.isError()) if (result.isError())
{ {
...@@ -554,6 +556,8 @@ egl::Error DisplayEGL::makeCurrent(egl::Surface *drawSurface, ...@@ -554,6 +556,8 @@ egl::Error DisplayEGL::makeCurrent(egl::Surface *drawSurface,
egl::Surface *readSurface, egl::Surface *readSurface,
gl::Context *context) gl::Context *context)
{ {
CurrentNativeContext &currentContext = mCurrentNativeContexts[std::this_thread::get_id()];
EGLSurface newSurface = EGL_NO_SURFACE; EGLSurface newSurface = EGL_NO_SURFACE;
if (drawSurface) if (drawSurface)
{ {
...@@ -568,9 +572,14 @@ egl::Error DisplayEGL::makeCurrent(egl::Surface *drawSurface, ...@@ -568,9 +572,14 @@ egl::Error DisplayEGL::makeCurrent(egl::Surface *drawSurface,
newContext = contextEGL->getContext(); newContext = contextEGL->getContext();
} }
if (mEGL->makeCurrent(newSurface, newContext) == EGL_FALSE) if (newSurface != currentContext.surface || newContext != currentContext.context)
{ {
return egl::Error(mEGL->getError(), "eglMakeCurrent failed"); if (mEGL->makeCurrent(newSurface, newContext) == EGL_FALSE)
{
return egl::Error(mEGL->getError(), "eglMakeCurrent failed");
}
currentContext.surface = newSurface;
currentContext.context = newContext;
} }
return DisplayGL::makeCurrent(drawSurface, readSurface, context); return DisplayGL::makeCurrent(drawSurface, readSurface, context);
...@@ -583,6 +592,17 @@ gl::Version DisplayEGL::getMaxSupportedESVersion() const ...@@ -583,6 +592,17 @@ gl::Version DisplayEGL::getMaxSupportedESVersion() const
void DisplayEGL::destroyNativeContext(EGLContext context) void DisplayEGL::destroyNativeContext(EGLContext context)
{ {
// If this context is current, remove it from the tracking of current contexts to make sure we
// don't try to make it current again.
for (auto &currentContext : mCurrentNativeContexts)
{
if (currentContext.second.context == context)
{
currentContext.second.surface = EGL_NO_SURFACE;
currentContext.second.context = EGL_NO_CONTEXT;
}
}
mEGL->destroyContext(context); mEGL->destroyContext(context);
} }
...@@ -689,6 +709,10 @@ egl::Error DisplayEGL::createRenderer(EGLContext shareContext, ...@@ -689,6 +709,10 @@ egl::Error DisplayEGL::createRenderer(EGLContext shareContext,
<< "eglMakeCurrent failed with " << egl::Error(mEGL->getError()); << "eglMakeCurrent failed with " << egl::Error(mEGL->getError());
} }
CurrentNativeContext &currentContext = mCurrentNativeContexts[std::this_thread::get_id()];
currentContext.surface = EGL_NO_SURFACE;
currentContext.context = context;
std::unique_ptr<FunctionsGL> functionsGL(mEGL->makeFunctionsGL()); std::unique_ptr<FunctionsGL> functionsGL(mEGL->makeFunctionsGL());
functionsGL->initialize(mDisplayAttributes); functionsGL->initialize(mDisplayAttributes);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <thread>
#include <vector> #include <vector>
#include "libANGLE/renderer/gl/DisplayGL.h" #include "libANGLE/renderer/gl/DisplayGL.h"
...@@ -128,6 +129,13 @@ class DisplayEGL : public DisplayGL ...@@ -128,6 +129,13 @@ class DisplayEGL : public DisplayGL
egl::AttributeMap mDisplayAttributes; egl::AttributeMap mDisplayAttributes;
std::vector<EGLint> mConfigAttribList; std::vector<EGLint> mConfigAttribList;
struct CurrentNativeContext
{
EGLSurface surface = EGL_NO_SURFACE;
EGLContext context = EGL_NO_CONTEXT;
};
std::unordered_map<std::thread::id, CurrentNativeContext> mCurrentNativeContexts;
private: private:
void generateCaps(egl::Caps *outCaps) const override; void generateCaps(egl::Caps *outCaps) const override;
......
...@@ -188,7 +188,6 @@ void DisplayAndroid::terminate() ...@@ -188,7 +188,6 @@ void DisplayAndroid::terminate()
} }
mRenderer.reset(); mRenderer.reset();
mCurrentNativeContext.clear();
egl::Error result = mEGL->terminate(); egl::Error result = mEGL->terminate();
if (result.isError()) if (result.isError())
...@@ -273,7 +272,7 @@ egl::Error DisplayAndroid::makeCurrent(egl::Surface *drawSurface, ...@@ -273,7 +272,7 @@ egl::Error DisplayAndroid::makeCurrent(egl::Surface *drawSurface,
egl::Surface *readSurface, egl::Surface *readSurface,
gl::Context *context) gl::Context *context)
{ {
CurrentNativeContext &currentContext = mCurrentNativeContext[std::this_thread::get_id()]; CurrentNativeContext &currentContext = mCurrentNativeContexts[std::this_thread::get_id()];
EGLSurface newSurface = EGL_NO_SURFACE; EGLSurface newSurface = EGL_NO_SURFACE;
if (drawSurface) if (drawSurface)
...@@ -331,17 +330,6 @@ egl::Error DisplayAndroid::makeCurrent(egl::Surface *drawSurface, ...@@ -331,17 +330,6 @@ egl::Error DisplayAndroid::makeCurrent(egl::Surface *drawSurface,
void DisplayAndroid::destroyNativeContext(EGLContext context) void DisplayAndroid::destroyNativeContext(EGLContext context)
{ {
DisplayEGL::destroyNativeContext(context); DisplayEGL::destroyNativeContext(context);
// If this context is current, remove it from the tracking of current contexts to make sure we
// don't try to make it current again.
for (auto &currentContext : mCurrentNativeContext)
{
if (currentContext.second.context == context)
{
currentContext.second.surface = EGL_NO_SURFACE;
currentContext.second.context = EGL_NO_CONTEXT;
}
}
} }
void DisplayAndroid::generateExtensions(egl::DisplayExtensions *outExtensions) const void DisplayAndroid::generateExtensions(egl::DisplayExtensions *outExtensions) const
...@@ -373,7 +361,7 @@ egl::Error DisplayAndroid::createRenderer(EGLContext shareContext, ...@@ -373,7 +361,7 @@ egl::Error DisplayAndroid::createRenderer(EGLContext shareContext,
outRenderer->reset( outRenderer->reset(
new RendererEGL(std::move(functionsGL), mDisplayAttributes, this, context, attribs)); new RendererEGL(std::move(functionsGL), mDisplayAttributes, this, context, attribs));
CurrentNativeContext &currentContext = mCurrentNativeContext[std::this_thread::get_id()]; CurrentNativeContext &currentContext = mCurrentNativeContexts[std::this_thread::get_id()];
if (makeNewContextCurrent) if (makeNewContextCurrent)
{ {
currentContext.surface = mDummyPbuffer; currentContext.surface = mDummyPbuffer;
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <map> #include <map>
#include <string> #include <string>
#include <thread>
#include <vector> #include <vector>
#include "libANGLE/renderer/gl/egl/DisplayEGL.h" #include "libANGLE/renderer/gl/egl/DisplayEGL.h"
...@@ -69,13 +68,6 @@ class DisplayAndroid : public DisplayEGL ...@@ -69,13 +68,6 @@ class DisplayAndroid : public DisplayEGL
bool mSupportsSurfaceless; bool mSupportsSurfaceless;
EGLSurface mDummyPbuffer; EGLSurface mDummyPbuffer;
struct CurrentNativeContext
{
EGLSurface surface = EGL_NO_SURFACE;
EGLContext context = EGL_NO_CONTEXT;
};
std::unordered_map<std::thread::id, CurrentNativeContext> mCurrentNativeContext;
}; };
} // namespace rx } // namespace rx
......
...@@ -205,7 +205,7 @@ TEST_P(MultithreadingTest, MultiContextDraw) ...@@ -205,7 +205,7 @@ TEST_P(MultithreadingTest, MultiContextDraw)
TEST_P(MultithreadingTest, MultiCreateContext) TEST_P(MultithreadingTest, MultiCreateContext)
{ {
// Supported by CGL, GLX, and WGL (https://anglebug.com/4725) // Supported by CGL, GLX, and WGL (https://anglebug.com/4725)
ANGLE_SKIP_TEST_IF(!(IsWindows() || (IsLinux() && !IsOzone()) || IsOSX())); ANGLE_SKIP_TEST_IF(!(IsWindows() || IsLinux() || IsOSX()));
EGLWindow *window = getEGLWindow(); EGLWindow *window = getEGLWindow();
EGLDisplay dpy = window->getDisplay(); EGLDisplay dpy = window->getDisplay();
......
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