Commit 258e8718 by Geoff Lang Committed by Commit Bot

EGL: Support unvirtualized contexts and unsafe multithreading.

-Add a new renderer and context type to own native EGL contexts and handle destruction. -Track the current EGL surface and context per-thread. -Support unvirtualized contexts by creating a new context for every client context. BUG=angleproject:2464 Change-Id: Ib2efa1d88c771b4a78625e0e3546f6ed95678c91 Reviewed-on: https://chromium-review.googlesource.com/1110943 Commit-Queue: Geoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org>
parent 838f304d
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "libANGLE/renderer/gl/egl/ContextEGL.h"
namespace rx
{
ContextEGL::ContextEGL(const gl::ContextState &state, const std::shared_ptr<RendererEGL> &renderer)
: ContextGL(state, renderer), mRenderer(renderer)
{
}
ContextEGL::~ContextEGL()
{
}
EGLContext ContextEGL::getContext() const
{
return mRenderer->getContext();
}
}
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// ContextEGL.h: Context class for GL on Android/ChromeOS. Wraps a RendererEGL.
#ifndef LIBANGLE_RENDERER_GL_EGL_CONTEXTEGL_H_
#define LIBANGLE_RENDERER_GL_EGL_CONTEXTEGL_H_
#include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/renderer/gl/egl/RendererEGL.h"
namespace rx
{
class ContextEGL : public ContextGL
{
public:
ContextEGL(const gl::ContextState &state, const std::shared_ptr<RendererEGL> &renderer);
~ContextEGL() override;
EGLContext getContext() const;
private:
std::shared_ptr<RendererEGL> mRenderer;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_EGL_RENDEREREGL_H_
...@@ -16,7 +16,7 @@ namespace rx ...@@ -16,7 +16,7 @@ namespace rx
#define EGL_NO_CONFIG ((EGLConfig)0) #define EGL_NO_CONFIG ((EGLConfig)0)
DisplayEGL::DisplayEGL(const egl::DisplayState &state) DisplayEGL::DisplayEGL(const egl::DisplayState &state)
: DisplayGL(state), mEGL(nullptr), mConfig(EGL_NO_CONFIG), mContext(EGL_NO_CONTEXT) : DisplayGL(state), mEGL(nullptr), mConfig(EGL_NO_CONFIG)
{ {
} }
...@@ -31,7 +31,9 @@ std::string DisplayEGL::getVendorString() const ...@@ -31,7 +31,9 @@ std::string DisplayEGL::getVendorString() const
return vendor; return vendor;
} }
egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes) egl::Error DisplayEGL::initializeContext(EGLContext shareContext,
const egl::AttributeMap &eglAttributes,
EGLContext *outContext) const
{ {
gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion); gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
...@@ -82,11 +84,13 @@ egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes) ...@@ -82,11 +84,13 @@ egl::Error DisplayEGL::initializeContext(const egl::AttributeMap &eglAttributes)
contextAttribLists.push_back({EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}); contextAttribLists.push_back({EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE});
} }
EGLContext context = EGL_NO_CONTEXT;
for (const auto &attribList : contextAttribLists) for (const auto &attribList : contextAttribLists)
{ {
mContext = mEGL->createContext(mConfig, EGL_NO_CONTEXT, attribList.data()); context = mEGL->createContext(mConfig, shareContext, attribList.data());
if (mContext != EGL_NO_CONTEXT) if (context != EGL_NO_CONTEXT)
{ {
*outContext = context;
return egl::NoError(); return egl::NoError();
} }
} }
......
...@@ -23,12 +23,15 @@ class DisplayEGL : public DisplayGL ...@@ -23,12 +23,15 @@ class DisplayEGL : public DisplayGL
std::string getVendorString() const override; std::string getVendorString() const override;
virtual void destroyNativeContext(EGLContext context) = 0;
protected: protected:
egl::Error initializeContext(const egl::AttributeMap &eglAttributes); egl::Error initializeContext(EGLContext shareContext,
const egl::AttributeMap &eglAttributes,
EGLContext *outContext) const;
FunctionsEGL *mEGL; FunctionsEGL *mEGL;
EGLConfig mConfig; EGLConfig mConfig;
EGLContext mContext;
private: private:
void generateExtensions(egl::DisplayExtensions *outExtensions) const override; void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
......
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "libANGLE/renderer/gl/egl/RendererEGL.h"
#include "libANGLE/renderer/gl/egl/DisplayEGL.h"
namespace rx
{
RendererEGL::RendererEGL(std::unique_ptr<FunctionsGL> functionsGL,
const egl::AttributeMap &attribMap,
DisplayEGL *display,
EGLContext context)
: RendererGL(std::move(functionsGL), attribMap), mDisplay(display), mContext(context)
{
}
RendererEGL::~RendererEGL()
{
mDisplay->destroyNativeContext(mContext);
mContext = nullptr;
}
EGLContext RendererEGL::getContext() const
{
return mContext;
}
} // namespace rx
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// RendererEGL.h: Renderer class for GL on Android/ChromeOS. Owns an EGL context object.
#ifndef LIBANGLE_RENDERER_GL_EGL_RENDEREREGL_H_
#define LIBANGLE_RENDERER_GL_EGL_RENDEREREGL_H_
#include "libANGLE/renderer/gl/RendererGL.h"
namespace rx
{
class DisplayEGL;
class RendererEGL : public RendererGL
{
public:
RendererEGL(std::unique_ptr<FunctionsGL> functionsGL,
const egl::AttributeMap &attribMap,
DisplayEGL *display,
EGLContext context);
~RendererEGL() override;
EGLContext getContext() const;
private:
DisplayEGL *mDisplay;
EGLContext mContext;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_GL_EGL_RENDEREREGL_H_
...@@ -9,12 +9,15 @@ ...@@ -9,12 +9,15 @@
#include <android/native_window.h> #include <android/native_window.h>
#include "common/debug.h" #include "common/debug.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/Surface.h" #include "libANGLE/Surface.h"
#include "libANGLE/renderer/gl/ContextGL.h" #include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/renderer/gl/RendererGL.h" #include "libANGLE/renderer/gl/RendererGL.h"
#include "libANGLE/renderer/gl/egl/ContextEGL.h"
#include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h" #include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
#include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h" #include "libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h"
#include "libANGLE/renderer/gl/egl/RendererEGL.h"
#include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h" #include "libANGLE/renderer/gl/egl/WindowSurfaceEGL.h"
#include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h" #include "libANGLE/renderer/gl/egl/android/DisplayAndroid.h"
#include "libANGLE/renderer/gl/renderergl_utils.h" #include "libANGLE/renderer/gl/renderergl_utils.h"
...@@ -34,8 +37,12 @@ const char *GetEGLPath() ...@@ -34,8 +37,12 @@ const char *GetEGLPath()
namespace rx namespace rx
{ {
static constexpr bool kDefaultEGLVirtualizedContexts = true;
DisplayAndroid::DisplayAndroid(const egl::DisplayState &state) DisplayAndroid::DisplayAndroid(const egl::DisplayState &state)
: DisplayEGL(state), mDummyPbuffer(EGL_NO_SURFACE), mCurrentSurface(EGL_NO_SURFACE) : DisplayEGL(state),
mVirtualizedContexts(kDefaultEGLVirtualizedContexts),
mDummyPbuffer(EGL_NO_SURFACE)
{ {
} }
...@@ -45,10 +52,14 @@ DisplayAndroid::~DisplayAndroid() ...@@ -45,10 +52,14 @@ DisplayAndroid::~DisplayAndroid()
egl::Error DisplayAndroid::initialize(egl::Display *display) egl::Error DisplayAndroid::initialize(egl::Display *display)
{ {
mDisplayAttributes = display->getAttributeMap();
mVirtualizedContexts =
ShouldUseVirtualizedContexts(mDisplayAttributes, kDefaultEGLVirtualizedContexts);
FunctionsEGLDL *egl = new FunctionsEGLDL(); FunctionsEGLDL *egl = new FunctionsEGLDL();
mEGL = egl; mEGL = egl;
void *eglHandle = reinterpret_cast<void *>(display->getAttributeMap().get( void *eglHandle =
EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE, 0)); reinterpret_cast<void *>(mDisplayAttributes.get(EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE, 0));
ANGLE_TRY(egl->initialize(display->getNativeDisplayId(), GetEGLPath(), eglHandle)); ANGLE_TRY(egl->initialize(display->getNativeDisplayId(), GetEGLPath(), eglHandle));
gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion); gl::Version eglVersion(mEGL->majorVersion, mEGL->minorVersion);
...@@ -140,20 +151,7 @@ egl::Error DisplayAndroid::initialize(egl::Display *display) ...@@ -140,20 +151,7 @@ egl::Error DisplayAndroid::initialize(egl::Display *display)
mConfig = configWithFormat; mConfig = configWithFormat;
} }
ANGLE_TRY(initializeContext(display->getAttributeMap())); ANGLE_TRY(createRenderer(EGL_NO_CONTEXT, true, &mRenderer));
success = mEGL->makeCurrent(mDummyPbuffer, mContext);
if (success == EGL_FALSE)
{
return egl::EglNotInitialized()
<< "eglMakeCurrent failed with " << egl::Error(mEGL->getError());
}
mCurrentSurface = mDummyPbuffer;
std::unique_ptr<FunctionsGL> functionsGL(mEGL->makeFunctionsGL());
functionsGL->initialize(display->getAttributeMap());
mRenderer.reset(new RendererGL(std::move(functionsGL), display->getAttributeMap()));
const gl::Version &maxVersion = mRenderer->getMaxSupportedESVersion(); const gl::Version &maxVersion = mRenderer->getMaxSupportedESVersion();
if (maxVersion < gl::Version(2, 0)) if (maxVersion < gl::Version(2, 0))
...@@ -173,7 +171,6 @@ void DisplayAndroid::terminate() ...@@ -173,7 +171,6 @@ void DisplayAndroid::terminate()
{ {
ERR() << "eglMakeCurrent error " << egl::Error(mEGL->getError()); ERR() << "eglMakeCurrent error " << egl::Error(mEGL->getError());
} }
mCurrentSurface = EGL_NO_SURFACE;
if (mDummyPbuffer != EGL_NO_SURFACE) if (mDummyPbuffer != EGL_NO_SURFACE)
{ {
...@@ -186,15 +183,7 @@ void DisplayAndroid::terminate() ...@@ -186,15 +183,7 @@ void DisplayAndroid::terminate()
} }
mRenderer.reset(); mRenderer.reset();
if (mContext != EGL_NO_CONTEXT) mCurrentNativeContext.clear();
{
success = mEGL->destroyContext(mContext);
mContext = EGL_NO_CONTEXT;
if (success == EGL_FALSE)
{
ERR() << "eglDestroyContext error " << egl::Error(mEGL->getError());
}
}
egl::Error result = mEGL->terminate(); egl::Error result = mEGL->terminate();
if (result.isError()) if (result.isError())
...@@ -264,7 +253,32 @@ ContextImpl *DisplayAndroid::createContext(const gl::ContextState &state, ...@@ -264,7 +253,32 @@ ContextImpl *DisplayAndroid::createContext(const gl::ContextState &state,
const gl::Context *shareContext, const gl::Context *shareContext,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
return new ContextGL(state, mRenderer); std::shared_ptr<RendererEGL> renderer;
if (mVirtualizedContexts)
{
renderer = mRenderer;
}
else
{
EGLContext nativeShareContext = EGL_NO_CONTEXT;
if (shareContext)
{
ContextEGL *shareContextEGL = GetImplAs<ContextEGL>(shareContext);
nativeShareContext = shareContextEGL->getContext();
}
// Create a new renderer for this context. It only needs to share with the user's requested
// share context because there are no internal resources in DisplayAndroid that are shared
// at the GL level.
egl::Error error = createRenderer(nativeShareContext, false, &renderer);
if (error.isError())
{
ERR() << "Failed to create a shared renderer: " << error.getMessage();
return nullptr;
}
}
return new ContextEGL(state, renderer);
} }
template <typename T> template <typename T>
...@@ -456,22 +470,45 @@ egl::Error DisplayAndroid::waitNative(const gl::Context *context, EGLint engine) ...@@ -456,22 +470,45 @@ egl::Error DisplayAndroid::waitNative(const gl::Context *context, EGLint engine)
UNIMPLEMENTED(); UNIMPLEMENTED();
return egl::NoError(); return egl::NoError();
} }
egl::Error DisplayAndroid::makeCurrent(egl::Surface *drawSurface, 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()];
EGLSurface newSurface = EGL_NO_SURFACE;
if (drawSurface) if (drawSurface)
{ {
SurfaceEGL *drawSurfaceEGL = GetImplAs<SurfaceEGL>(drawSurface); SurfaceEGL *drawSurfaceEGL = GetImplAs<SurfaceEGL>(drawSurface);
EGLSurface surface = drawSurfaceEGL->getSurface(); newSurface = drawSurfaceEGL->getSurface();
if (surface != mCurrentSurface) }
EGLContext newContext = EGL_NO_CONTEXT;
if (context)
{
ContextEGL *contextEGL = GetImplAs<ContextEGL>(context);
newContext = contextEGL->getContext();
}
// The context should never change when context virtualization is being used, even when a null
// context is being bound.
if (mVirtualizedContexts)
{
ASSERT(newContext == EGL_NO_CONTEXT || currentContext.context == EGL_NO_CONTEXT ||
newContext == currentContext.context);
newContext = mRenderer->getContext();
}
if (newSurface != currentContext.surface || newContext != currentContext.context)
{
if (mEGL->makeCurrent(newSurface, newContext) == EGL_FALSE)
{ {
if (mEGL->makeCurrent(surface, mContext) == EGL_FALSE) return egl::Error(mEGL->getError(), "eglMakeCurrent failed");
{
return egl::Error(mEGL->getError(), "eglMakeCurrent failed");
}
mCurrentSurface = surface;
} }
currentContext.surface = newSurface;
currentContext.context = newContext;
} }
return DisplayGL::makeCurrent(drawSurface, readSurface, context); return DisplayGL::makeCurrent(drawSurface, readSurface, context);
...@@ -482,6 +519,22 @@ gl::Version DisplayAndroid::getMaxSupportedESVersion() const ...@@ -482,6 +519,22 @@ gl::Version DisplayAndroid::getMaxSupportedESVersion() const
return mRenderer->getMaxSupportedESVersion(); return mRenderer->getMaxSupportedESVersion();
} }
void DisplayAndroid::destroyNativeContext(EGLContext context)
{
mEGL->destroyContext(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;
}
}
}
egl::Error DisplayAndroid::makeCurrentSurfaceless(gl::Context *context) egl::Error DisplayAndroid::makeCurrentSurfaceless(gl::Context *context)
{ {
// Nothing to do because EGL always uses the same context and the previous surface can be left // Nothing to do because EGL always uses the same context and the previous surface can be left
...@@ -489,4 +542,41 @@ egl::Error DisplayAndroid::makeCurrentSurfaceless(gl::Context *context) ...@@ -489,4 +542,41 @@ egl::Error DisplayAndroid::makeCurrentSurfaceless(gl::Context *context)
return egl::NoError(); return egl::NoError();
} }
egl::Error DisplayAndroid::createRenderer(EGLContext shareContext,
bool makeNewContextCurrent,
std::shared_ptr<RendererEGL> *outRenderer)
{
EGLContext context = EGL_NO_CONTEXT;
ANGLE_TRY(initializeContext(shareContext, mDisplayAttributes, &context));
if (mEGL->makeCurrent(mDummyPbuffer, context) == EGL_FALSE)
{
return egl::EglNotInitialized()
<< "eglMakeCurrent failed with " << egl::Error(mEGL->getError());
}
std::unique_ptr<FunctionsGL> functionsGL(mEGL->makeFunctionsGL());
functionsGL->initialize(mDisplayAttributes);
outRenderer->reset(new RendererEGL(std::move(functionsGL), mDisplayAttributes, this, context));
CurrentNativeContext &currentContext = mCurrentNativeContext[std::this_thread::get_id()];
if (makeNewContextCurrent)
{
currentContext.surface = mDummyPbuffer;
currentContext.context = context;
}
else
{
// Reset the current context back to the previous state
if (mEGL->makeCurrent(currentContext.surface, currentContext.context) == EGL_FALSE)
{
return egl::EglNotInitialized()
<< "eglMakeCurrent failed with " << egl::Error(mEGL->getError());
}
}
return egl::NoError();
}
} // namespace rx } // namespace rx
...@@ -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/egl/DisplayEGL.h" #include "libANGLE/renderer/gl/egl/DisplayEGL.h"
...@@ -18,6 +19,8 @@ ...@@ -18,6 +19,8 @@
namespace rx namespace rx
{ {
class RendererEGL;
class DisplayAndroid : public DisplayEGL class DisplayAndroid : public DisplayEGL
{ {
public: public:
...@@ -67,7 +70,13 @@ class DisplayAndroid : public DisplayEGL ...@@ -67,7 +70,13 @@ class DisplayAndroid : public DisplayEGL
gl::Version getMaxSupportedESVersion() const override; gl::Version getMaxSupportedESVersion() const override;
void destroyNativeContext(EGLContext context) override;
private: private:
egl::Error createRenderer(EGLContext shareContext,
bool makeNewContextCurrent,
std::shared_ptr<RendererEGL> *outRenderer);
egl::Error makeCurrentSurfaceless(gl::Context *context) override; egl::Error makeCurrentSurfaceless(gl::Context *context) override;
template <typename T> template <typename T>
...@@ -80,12 +89,21 @@ class DisplayAndroid : public DisplayEGL ...@@ -80,12 +89,21 @@ class DisplayAndroid : public DisplayEGL
const char *extension, const char *extension,
const U &defaultValue) const; const U &defaultValue) const;
std::shared_ptr<RendererGL> mRenderer; bool mVirtualizedContexts;
std::shared_ptr<RendererEGL> mRenderer;
egl::AttributeMap mDisplayAttributes;
std::vector<EGLint> mConfigAttribList; std::vector<EGLint> mConfigAttribList;
std::map<EGLint, EGLint> mConfigIds; std::map<EGLint, EGLint> mConfigIds;
EGLSurface mDummyPbuffer; EGLSurface mDummyPbuffer;
EGLSurface mCurrentSurface;
struct CurrentNativeContext
{
EGLSurface surface = EGL_NO_SURFACE;
EGLContext context = EGL_NO_CONTEXT;
};
std::unordered_map<std::thread::id, CurrentNativeContext> mCurrentNativeContext;
}; };
} // namespace rx } // namespace rx
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "libANGLE/renderer/gl/FramebufferGL.h" #include "libANGLE/renderer/gl/FramebufferGL.h"
#include "libANGLE/renderer/gl/RendererGL.h" #include "libANGLE/renderer/gl/RendererGL.h"
#include "libANGLE/renderer/gl/StateManagerGL.h" #include "libANGLE/renderer/gl/StateManagerGL.h"
#include "libANGLE/renderer/gl/egl/ContextEGL.h"
#include "libANGLE/renderer/gl/egl/DisplayEGL.h"
#include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h" #include "libANGLE/renderer/gl/egl/FunctionsEGLDL.h"
#include "libANGLE/renderer/gl/egl/ozone/SurfaceOzone.h" #include "libANGLE/renderer/gl/egl/ozone/SurfaceOzone.h"
#include "platform/Platform.h" #include "platform/Platform.h"
...@@ -524,9 +526,10 @@ egl::Error DisplayOzone::initialize(egl::Display *display) ...@@ -524,9 +526,10 @@ egl::Error DisplayOzone::initialize(egl::Display *display)
mConfig = config[0]; mConfig = config[0];
} }
ANGLE_TRY(initializeContext(display->getAttributeMap())); EGLContext context = EGL_NO_CONTEXT;
ANGLE_TRY(initializeContext(EGL_NO_CONTEXT, display->getAttributeMap(), &context));
if (!mEGL->makeCurrent(EGL_NO_SURFACE, mContext)) if (!mEGL->makeCurrent(EGL_NO_SURFACE, context))
{ {
return egl::EglNotInitialized() << "Could not make context current."; return egl::EglNotInitialized() << "Could not make context current.";
} }
...@@ -534,7 +537,8 @@ egl::Error DisplayOzone::initialize(egl::Display *display) ...@@ -534,7 +537,8 @@ egl::Error DisplayOzone::initialize(egl::Display *display)
std::unique_ptr<FunctionsGL> functionsGL(mEGL->makeFunctionsGL()); std::unique_ptr<FunctionsGL> functionsGL(mEGL->makeFunctionsGL());
functionsGL->initialize(display->getAttributeMap()); functionsGL->initialize(display->getAttributeMap());
mRenderer.reset(new RendererGL(std::move(functionsGL), display->getAttributeMap())); mRenderer.reset(
new RendererEGL(std::move(functionsGL), display->getAttributeMap(), this, context));
const gl::Version &maxVersion = mRenderer->getMaxSupportedESVersion(); const gl::Version &maxVersion = mRenderer->getMaxSupportedESVersion();
if (maxVersion < gl::Version(2, 0)) if (maxVersion < gl::Version(2, 0))
{ {
...@@ -855,19 +859,14 @@ void DisplayOzone::terminate() ...@@ -855,19 +859,14 @@ void DisplayOzone::terminate()
DisplayGL::terminate(); DisplayGL::terminate();
if (mContext)
{
// Mesa might crash if you terminate EGL with a context current
// then re-initialize EGL, so make our context not current.
mEGL->makeCurrent(EGL_NO_SURFACE, EGL_NO_CONTEXT);
mEGL->destroyContext(mContext);
mContext = nullptr;
}
mRenderer.reset(); mRenderer.reset();
if (mEGL) if (mEGL)
{ {
// Mesa might crash if you terminate EGL with a context current then re-initialize EGL, so
// make our context not current.
mEGL->makeCurrent(EGL_NO_SURFACE, EGL_NO_CONTEXT);
ANGLE_SWALLOW_ERR(mEGL->terminate()); ANGLE_SWALLOW_ERR(mEGL->terminate());
SafeDelete(mEGL); SafeDelete(mEGL);
} }
...@@ -936,7 +935,8 @@ ContextImpl *DisplayOzone::createContext(const gl::ContextState &state, ...@@ -936,7 +935,8 @@ ContextImpl *DisplayOzone::createContext(const gl::ContextState &state,
const gl::Context *shareContext, const gl::Context *shareContext,
const egl::AttributeMap &attribs) const egl::AttributeMap &attribs)
{ {
return new ContextGL(state, mRenderer); // All contexts on Ozone are virtualized and share the same renderer.
return new ContextEGL(state, mRenderer);
} }
DeviceImpl *DisplayOzone::createDevice() DeviceImpl *DisplayOzone::createDevice()
...@@ -999,6 +999,11 @@ gl::Version DisplayOzone::getMaxSupportedESVersion() const ...@@ -999,6 +999,11 @@ gl::Version DisplayOzone::getMaxSupportedESVersion() const
return mRenderer->getMaxSupportedESVersion(); return mRenderer->getMaxSupportedESVersion();
} }
void DisplayOzone::destroyNativeContext(EGLContext context)
{
mEGL->destroyContext(context);
}
void DisplayOzone::setSwapInterval(EGLSurface drawable, SwapControlData *data) void DisplayOzone::setSwapInterval(EGLSurface drawable, SwapControlData *data)
{ {
ASSERT(data != nullptr); ASSERT(data != nullptr);
......
...@@ -28,6 +28,7 @@ namespace rx ...@@ -28,6 +28,7 @@ namespace rx
{ {
class FramebufferGL; class FramebufferGL;
class RendererEGL;
// TODO(fjhenigman) Implement swap control. The following struct will be used for that. // TODO(fjhenigman) Implement swap control. The following struct will be used for that.
// State-tracking data for the swap control to allow DisplayOzone to remember per // State-tracking data for the swap control to allow DisplayOzone to remember per
...@@ -146,6 +147,8 @@ class DisplayOzone final : public DisplayEGL ...@@ -146,6 +147,8 @@ class DisplayOzone final : public DisplayEGL
gl::Version getMaxSupportedESVersion() const override; gl::Version getMaxSupportedESVersion() const override;
void destroyNativeContext(EGLContext context) override;
// TODO(fjhenigman) Implement this. // TODO(fjhenigman) Implement this.
// Swap interval can be set globally or per drawable. // Swap interval can be set globally or per drawable.
// This function will make sure the drawable's swap interval is the // This function will make sure the drawable's swap interval is the
...@@ -168,7 +171,7 @@ class DisplayOzone final : public DisplayEGL ...@@ -168,7 +171,7 @@ class DisplayOzone final : public DisplayEGL
void *data); void *data);
void pageFlipHandler(unsigned int sequence, uint64_t tv); void pageFlipHandler(unsigned int sequence, uint64_t tv);
std::shared_ptr<RendererGL> mRenderer; std::shared_ptr<RendererEGL> mRenderer;
gbm_device *mGBM; gbm_device *mGBM;
drmModeConnectorPtr mConnector; drmModeConnectorPtr mConnector;
......
...@@ -717,6 +717,8 @@ ...@@ -717,6 +717,8 @@
], ],
'libangle_gl_egl_sources': 'libangle_gl_egl_sources':
[ [
'libANGLE/renderer/gl/egl/ContextEGL.cpp',
'libANGLE/renderer/gl/egl/ContextEGL.h',
'libANGLE/renderer/gl/egl/DisplayEGL.cpp', 'libANGLE/renderer/gl/egl/DisplayEGL.cpp',
'libANGLE/renderer/gl/egl/DisplayEGL.h', 'libANGLE/renderer/gl/egl/DisplayEGL.h',
'libANGLE/renderer/gl/egl/egl_utils.cpp', 'libANGLE/renderer/gl/egl/egl_utils.cpp',
...@@ -726,6 +728,8 @@ ...@@ -726,6 +728,8 @@
'libANGLE/renderer/gl/egl/functionsegl_typedefs.h', 'libANGLE/renderer/gl/egl/functionsegl_typedefs.h',
'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp', 'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.cpp',
'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h', 'libANGLE/renderer/gl/egl/PbufferSurfaceEGL.h',
'libANGLE/renderer/gl/egl/RendererEGL.cpp',
'libANGLE/renderer/gl/egl/RendererEGL.h',
'libANGLE/renderer/gl/egl/SurfaceEGL.cpp', 'libANGLE/renderer/gl/egl/SurfaceEGL.cpp',
'libANGLE/renderer/gl/egl/SurfaceEGL.h', 'libANGLE/renderer/gl/egl/SurfaceEGL.h',
'libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp', 'libANGLE/renderer/gl/egl/WindowSurfaceEGL.cpp',
......
...@@ -29,7 +29,7 @@ class MultithreadingTest : public ANGLETest ...@@ -29,7 +29,7 @@ class MultithreadingTest : public ANGLETest
setContextVirtualization(false); setContextVirtualization(false);
} }
bool platformSupportsMultithreading() const { return false; } bool platformSupportsMultithreading() const { return (IsOpenGLES() && IsAndroid()); }
}; };
// Test that it's possible to make one context current on different threads // Test that it's possible to make one context current on different threads
......
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