From dac9cdd04c8a559810b46743e6cbe17a97a15b95 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Mon, 1 Feb 2021 01:27:14 +1000 Subject: [PATCH] GL/Context: Ensure context is destroyed before GBM device Fixes crash on shutdown when running under DRM/KMS. --- src/common/gl/context_egl.cpp | 31 ++++++++++++++++++++++++++----- src/common/gl/context_egl.h | 2 ++ src/common/gl/context_egl_gbm.cpp | 5 +++++ 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/common/gl/context_egl.cpp b/src/common/gl/context_egl.cpp index 6a034da39..34da54ba9 100644 --- a/src/common/gl/context_egl.cpp +++ b/src/common/gl/context_egl.cpp @@ -10,11 +10,8 @@ ContextEGL::ContextEGL(const WindowInfo& wi) : Context(wi) {} ContextEGL::~ContextEGL() { - if (eglGetCurrentContext() == m_context) - eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - if (m_context) - eglDestroyContext(m_display, m_context); + DestroySurface(); + DestroyContext(); } std::unique_ptr 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) { Log_DevPrintf( diff --git a/src/common/gl/context_egl.h b/src/common/gl/context_egl.h index 368588664..79dc6b049 100644 --- a/src/common/gl/context_egl.h +++ b/src/common/gl/context_egl.h @@ -33,6 +33,8 @@ protected: bool CreateSurface(); bool CreatePBufferSurface(); bool CheckConfigSurfaceFormat(EGLConfig config, WindowInfo::SurfaceFormat format) const; + void DestroyContext(); + void DestroySurface(); EGLDisplay m_display = EGL_NO_DISPLAY; EGLSurface m_surface = EGL_NO_SURFACE; diff --git a/src/common/gl/context_egl_gbm.cpp b/src/common/gl/context_egl_gbm.cpp index 3a27f684b..57ca2be88 100644 --- a/src/common/gl/context_egl_gbm.cpp +++ b/src/common/gl/context_egl_gbm.cpp @@ -21,6 +21,11 @@ ContextEGLGBM::~ContextEGLGBM() Assert(!m_current_present_buffer); #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) { Buffer& buffer = m_buffers[--m_num_buffers];