GL/Context: Ensure context is destroyed before GBM device

Fixes crash on shutdown when running under DRM/KMS.
This commit is contained in:
Connor McLaughlin 2021-02-01 01:27:14 +10:00
parent 1a9120135f
commit dac9cdd04c
3 changed files with 33 additions and 5 deletions

View file

@ -10,11 +10,8 @@ ContextEGL::ContextEGL(const WindowInfo& wi) : Context(wi) {}
ContextEGL::~ContextEGL() ContextEGL::~ContextEGL()
{ {
if (eglGetCurrentContext() == m_context) DestroySurface();
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); DestroyContext();
if (m_context)
eglDestroyContext(m_display, m_context);
} }
std::unique_ptr<Context> ContextEGL::Create(const WindowInfo& wi, const Version* versions_to_try, std::unique_ptr<Context> ContextEGL::Create(const WindowInfo& wi, const Version* versions_to_try,
@ -256,6 +253,30 @@ bool ContextEGL::CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceF
} }
} }
void ContextEGL::DestroyContext()
{
if (eglGetCurrentContext() == m_context)
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (m_context != EGL_NO_CONTEXT)
{
eglDestroyContext(m_display, m_context);
m_context = EGL_NO_CONTEXT;
}
}
void ContextEGL::DestroySurface()
{
if (eglGetCurrentSurface(EGL_DRAW) == m_surface)
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (m_surface != EGL_NO_SURFACE)
{
eglDestroySurface(m_display, m_surface);
m_surface = EGL_NO_SURFACE;
}
}
bool ContextEGL::CreateContext(const Version& version, EGLContext share_context) bool ContextEGL::CreateContext(const Version& version, EGLContext share_context)
{ {
Log_DevPrintf( Log_DevPrintf(

View file

@ -33,6 +33,8 @@ protected:
bool CreateSurface(); bool CreateSurface();
bool CreatePBufferSurface(); bool CreatePBufferSurface();
bool CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceFormat format) const; bool CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceFormat format) const;
void DestroyContext();
void DestroySurface();
EGLDisplay m_display = EGL_NO_DISPLAY; EGLDisplay m_display = EGL_NO_DISPLAY;
EGLSurface m_surface = EGL_NO_SURFACE; EGLSurface m_surface = EGL_NO_SURFACE;

View file

@ -21,6 +21,11 @@ ContextEGLGBM::~ContextEGLGBM()
Assert(!m_current_present_buffer); Assert(!m_current_present_buffer);
#endif #endif
// We have to destroy the context before the surface/device.
// Leaving it to the base class would be too late.
DestroySurface();
DestroyContext();
while (m_num_buffers > 0) while (m_num_buffers > 0)
{ {
Buffer& buffer = m_buffers[--m_num_buffers]; Buffer& buffer = m_buffers[--m_num_buffers];