GLContext: Use destructor instead of Shutdown() to cleanup

Also uses the Initialize() method to make the context current.
This commit is contained in:
Stenzek 2018-10-03 23:03:33 +10:00
parent 4b8d1c2b42
commit 025e909773
16 changed files with 122 additions and 115 deletions

View File

@ -50,10 +50,6 @@ bool GLContext::ClearCurrent()
return false;
}
void GLContext::Shutdown()
{
}
void GLContext::Update()
{
}

View File

@ -31,7 +31,6 @@ public:
virtual bool IsHeadless() const;
virtual std::unique_ptr<GLContext> CreateSharedContext();
virtual void Shutdown();
virtual bool MakeCurrent();
virtual bool ClearCurrent();
@ -44,7 +43,8 @@ public:
virtual void* GetFuncAddress(const std::string& name);
// Creates an instance of GLInterface specific to the platform we are running on.
// Creates an instance of GLContext specific to the platform we are running on.
// If successful, the context is made current on the calling thread.
static std::unique_ptr<GLContext> Create(const WindowSystemInfo& wsi, bool stereo = false,
bool core = true);
@ -56,6 +56,5 @@ protected:
// Window dimensions.
u32 m_backbuffer_width = 0;
u32 m_backbuffer_height = 0;
bool m_is_core_context = false;
bool m_is_shared = false;
};

View File

@ -14,13 +14,14 @@ struct NSView;
#include "Common/GL/GLContext.h"
class GLContextAGL : public GLContext
class GLContextAGL final : public GLContext
{
public:
~GLContextAGL() override;
bool IsHeadless() const override;
std::unique_ptr<GLContext> CreateSharedContext() override;
void Shutdown() override;
bool MakeCurrent() override;
bool ClearCurrent() override;

View File

@ -43,6 +43,20 @@ static bool AttachContextToView(NSOpenGLContext* context, NSView* view, u32* wid
return true;
}
GLContextAGL::~GLContextAGL()
{
if ([NSOpenGLContext currentContext] == m_context)
[NSOpenGLContext clearCurrentContext];
if (m_context)
{
[m_context clearDrawable];
[m_context release];
}
if (m_pixel_format)
[m_pixel_format release];
}
bool GLContextAGL::IsHeadless() const
{
return !m_view;
@ -83,7 +97,11 @@ bool GLContextAGL::Initialize(void* display_handle, void* window_handle, bool st
m_view = static_cast<NSView*>(window_handle);
m_opengl_mode = Mode::OpenGL;
return AttachContextToView(m_context, m_view, &m_backbuffer_width, &m_backbuffer_height);
if (!AttachContextToView(m_context, m_view, &m_backbuffer_width, &m_backbuffer_height))
return false;
[m_context makeCurrentContext];
return true;
}
std::unique_ptr<GLContext> GLContextAGL::CreateSharedContext()
@ -100,6 +118,7 @@ std::unique_ptr<GLContext> GLContextAGL::CreateSharedContext()
new_context->m_context = new_agl_context;
new_context->m_pixel_format = m_pixel_format;
[new_context->m_pixel_format retain];
new_context->m_is_shared = true;
return new_context;
}
@ -115,16 +134,6 @@ bool GLContextAGL::ClearCurrent()
return true;
}
// Close backend
void GLContextAGL::Shutdown()
{
[m_context clearDrawable];
[m_context release];
m_context = nil;
[m_pixel_format release];
m_pixel_format = nil;
}
void GLContextAGL::Update()
{
if (!m_view)

View File

@ -28,7 +28,11 @@
#define EGL_OPENGL_ES3_BIT_KHR 0x00000040
#endif /* EGL_KHR_create_context */
GLContextEGL::~GLContextEGL() = default;
GLContextEGL::~GLContextEGL()
{
DestroyWindowSurface();
DestroyContext();
}
bool GLContextEGL::IsHeadless() const
{
@ -162,7 +166,6 @@ bool GLContextEGL::Initialize(void* display_handle, void* window_handle, bool st
m_host_display = display_handle;
m_host_window = window_handle;
m_egl_display = OpenEGLDisplay();
m_is_core_context = core;
if (!m_egl_display)
{
@ -268,7 +271,6 @@ bool GLContextEGL::Initialize(void* display_handle, void* window_handle, bool st
if (!m_egl_context)
{
m_is_core_context = false;
m_egl_context = eglCreateContext(m_egl_display, m_config, EGL_NO_CONTEXT, &ctx_attribs[0]);
m_attribs = std::move(ctx_attribs);
}
@ -284,7 +286,8 @@ bool GLContextEGL::Initialize(void* display_handle, void* window_handle, bool st
ERROR_LOG(VIDEO, "Error: CreateWindowSurface failed 0x%04x", eglGetError());
return false;
}
return true;
return MakeCurrent();
}
std::unique_ptr<GLContext> GLContextEGL::CreateSharedContext()
@ -303,7 +306,6 @@ std::unique_ptr<GLContext> GLContextEGL::CreateSharedContext()
new_context->m_egl_context = new_egl_context;
new_context->m_host_display = m_host_display;
new_context->m_egl_display = m_egl_display;
new_context->m_is_core_context = m_is_core_context;
new_context->m_config = m_config;
new_context->m_supports_surfaceless = m_supports_surfaceless;
new_context->m_is_shared = true;
@ -349,7 +351,12 @@ bool GLContextEGL::CreateWindowSurface()
void GLContextEGL::DestroyWindowSurface()
{
if (m_egl_surface != EGL_NO_SURFACE && !eglDestroySurface(m_egl_display, m_egl_surface))
if (m_egl_surface == EGL_NO_SURFACE)
return;
if (eglGetCurrentSurface(EGL_DRAW) == m_egl_surface)
eglMakeCurrent(m_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!eglDestroySurface(m_egl_display, m_egl_surface))
NOTICE_LOG(VIDEO, "Could not destroy window surface.");
m_egl_surface = EGL_NO_SURFACE;
}
@ -374,18 +381,17 @@ bool GLContextEGL::ClearCurrent()
}
// Close backend
void GLContextEGL::Shutdown()
void GLContextEGL::DestroyContext()
{
if (m_egl_context)
{
if (!eglMakeCurrent(m_egl_display, m_egl_surface, m_egl_surface, m_egl_context))
NOTICE_LOG(VIDEO, "Could not release drawing context.");
if (!m_egl_context)
return;
if (eglGetCurrentContext() == m_egl_context)
eglMakeCurrent(m_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (!eglDestroyContext(m_egl_display, m_egl_context))
NOTICE_LOG(VIDEO, "Could not destroy drawing context.");
DestroyWindowSurface();
if (!m_is_shared && !eglTerminate(m_egl_display))
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
m_egl_context = nullptr;
}
if (!eglDestroyContext(m_egl_display, m_egl_context))
NOTICE_LOG(VIDEO, "Could not destroy drawing context.");
if (!m_is_shared && !eglTerminate(m_egl_display))
NOTICE_LOG(VIDEO, "Could not destroy display connection.");
m_egl_context = EGL_NO_CONTEXT;
m_egl_display = EGL_NO_DISPLAY;
}

View File

@ -14,12 +14,11 @@
class GLContextEGL : public GLContext
{
public:
virtual ~GLContextEGL();
virtual ~GLContextEGL() override;
bool IsHeadless() const override;
std::unique_ptr<GLContext> CreateSharedContext() override;
virtual void Shutdown() override;
bool MakeCurrent() override;
bool ClearCurrent() override;
@ -40,6 +39,7 @@ protected:
bool CreateWindowSurface();
void DestroyWindowSurface();
void DetectMode(bool has_handle);
void DestroyContext();
void* m_host_display = nullptr;
void* m_host_window = nullptr;
@ -48,7 +48,7 @@ protected:
bool m_supports_surfaceless = false;
std::vector<int> m_attribs;
EGLSurface m_egl_surface;
EGLContext m_egl_context;
EGLDisplay m_egl_display;
EGLSurface m_egl_surface = EGL_NO_SURFACE;
EGLContext m_egl_context = EGL_NO_CONTEXT;
EGLDisplay m_egl_display = EGL_NO_DISPLAY;
};

View File

@ -6,7 +6,7 @@
#include "Common/GL/GLInterface/EGL.h"
class GLContextEGLAndroid : public GLContextEGL
class GLContextEGLAndroid final : public GLContextEGL
{
protected:
EGLDisplay OpenEGLDisplay() override;

View File

@ -4,7 +4,13 @@
#include "Common/GL/GLInterface/EGLX11.h"
GLContextEGLX11::~GLContextEGLX11() = default;
GLContextEGLX11::~GLContextEGLX11()
{
// The context must be destroyed before the window.
DestroyWindowSurface();
DestroyContext();
m_render_window.reset();
}
void GLContextEGLX11::Update()
{

View File

@ -9,7 +9,7 @@
#include "Common/GL/GLInterface/EGL.h"
#include "Common/GL/GLX11Window.h"
class GLContextEGLX11 : public GLContextEGL
class GLContextEGLX11 final : public GLContextEGL
{
public:
~GLContextEGLX11() override;

View File

@ -30,9 +30,21 @@ static int ctxErrorHandler(Display* dpy, XErrorEvent* ev)
return 0;
}
GLContextGLX::~GLContextGLX()
{
DestroyWindowSurface();
if (m_context)
{
if (glXGetCurrentContext() == m_context)
glXMakeCurrent(m_display, None, nullptr);
glXDestroyContext(m_display, m_context);
}
}
bool GLContextGLX::IsHeadless() const
{
return m_render_window == nullptr;
return !m_render_window;
}
void GLContextGLX::SwapInterval(int Interval)
@ -202,7 +214,7 @@ bool GLContextGLX::Initialize(void* display_handle, void* window_handle, bool st
XSetErrorHandler(oldHandler);
m_opengl_mode = Mode::OpenGL;
return true;
return MakeCurrent();
}
std::unique_ptr<GLContext> GLContextGLX::CreateSharedContext()
@ -227,6 +239,7 @@ std::unique_ptr<GLContext> GLContextGLX::CreateSharedContext()
new_context->m_supports_pbuffer = m_supports_pbuffer;
new_context->m_display = m_display;
new_context->m_fbconfig = m_fbconfig;
new_context->m_is_shared = true;
if (m_supports_pbuffer && !new_context->CreateWindowSurface(None))
{
@ -286,14 +299,6 @@ bool GLContextGLX::ClearCurrent()
return glXMakeCurrent(m_display, None, nullptr);
}
// Close backend
void GLContextGLX::Shutdown()
{
DestroyWindowSurface();
if (m_context)
glXDestroyContext(m_display, m_context);
}
void GLContextGLX::Update()
{
m_render_window->UpdateDimensions();

View File

@ -13,13 +13,14 @@
#include "Common/GL/GLContext.h"
#include "Common/GL/GLX11Window.h"
class GLContextGLX : public GLContext
class GLContextGLX final : public GLContext
{
public:
~GLContextGLX() override;
bool IsHeadless() const override;
std::unique_ptr<GLContext> CreateSharedContext() override;
void Shutdown() override;
bool MakeCurrent() override;
bool ClearCurrent() override;
@ -38,7 +39,7 @@ protected:
std::unique_ptr<GLX11Window> m_render_window;
GLXDrawable m_drawable = {};
GLXContext m_context = {};
GLXContext m_context = nullptr;
GLXFBConfig m_fbconfig = {};
bool m_supports_pbuffer = false;
GLXPbufferSGIX m_pbuffer = 0;

View File

@ -157,6 +157,39 @@ static void ClearWGLExtensionPointers()
wglDestroyPbufferARB = nullptr;
}
GLContextWGL::~GLContextWGL()
{
if (m_rc)
{
if (wglGetCurrentContext() == m_rc && !wglMakeCurrent(m_dc, nullptr))
NOTICE_LOG(VIDEO, "Could not release drawing context.");
if (!wglDeleteContext(m_rc))
ERROR_LOG(VIDEO, "Attempt to release rendering context failed.");
m_rc = nullptr;
}
if (m_dc)
{
if (m_pbuffer_handle)
{
wglReleasePbufferDCARB(static_cast<HPBUFFERARB>(m_pbuffer_handle), m_dc);
m_dc = nullptr;
wglDestroyPbufferARB(static_cast<HPBUFFERARB>(m_pbuffer_handle));
m_pbuffer_handle = nullptr;
}
else
{
if (!ReleaseDC(m_window_handle, m_dc))
ERROR_LOG(VIDEO, "Attempt to release device context failed.");
m_dc = nullptr;
}
}
}
bool GLContextWGL::IsHeadless() const
{
return !m_window_handle;
@ -295,7 +328,6 @@ bool GLContextWGL::Initialize(void* display_handle, void* window_handle, bool st
{
wglDeleteContext(m_rc);
m_rc = core_context;
m_is_core_context = true;
}
else
{
@ -303,7 +335,7 @@ bool GLContextWGL::Initialize(void* display_handle, void* window_handle, bool st
}
}
return true;
return MakeCurrent();
}
std::unique_ptr<GLContext> GLContextWGL::CreateSharedContext()
@ -327,7 +359,7 @@ std::unique_ptr<GLContext> GLContextWGL::CreateSharedContext()
context->m_dc = dc;
context->m_rc = rc;
context->m_opengl_mode = m_opengl_mode;
context->m_is_core_context = m_is_core_context;
context->m_is_shared = true;
return context;
}
@ -468,37 +500,3 @@ void GLContextWGL::Update()
m_backbuffer_width = rcWindow.right - rcWindow.left;
m_backbuffer_height = rcWindow.bottom - rcWindow.top;
}
// Close backend
void GLContextWGL::Shutdown()
{
if (m_rc)
{
if (!wglMakeCurrent(m_dc, nullptr))
NOTICE_LOG(VIDEO, "Could not release drawing context.");
if (!wglDeleteContext(m_rc))
ERROR_LOG(VIDEO, "Attempt to release rendering context failed.");
m_rc = nullptr;
}
if (m_dc)
{
if (m_pbuffer_handle)
{
wglReleasePbufferDCARB(static_cast<HPBUFFERARB>(m_pbuffer_handle), m_dc);
m_dc = nullptr;
wglDestroyPbufferARB(static_cast<HPBUFFERARB>(m_pbuffer_handle));
m_pbuffer_handle = nullptr;
}
else
{
if (!ReleaseDC(m_window_handle, m_dc))
ERROR_LOG(VIDEO, "Attempt to release device context failed.");
m_dc = nullptr;
}
}
}

View File

@ -8,16 +8,17 @@
#include <string>
#include "Common/GL/GLContext.h"
class GLContextWGL : public GLContext
class GLContextWGL final : public GLContext
{
public:
~GLContextWGL();
bool IsHeadless() const;
std::unique_ptr<GLContext> CreateSharedContext() override;
bool MakeCurrent() override;
bool ClearCurrent() override;
void Shutdown() override;
void Update() override;

View File

@ -803,11 +803,7 @@ Renderer::Renderer(std::unique_ptr<GLContext> main_gl_context)
ClearEFBCache();
}
Renderer::~Renderer()
{
m_main_gl_context->ClearCurrent();
m_main_gl_context->Shutdown();
}
Renderer::~Renderer() = default;
bool Renderer::IsHeadless() const
{

View File

@ -166,7 +166,6 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
if (!main_gl_context)
return false;
main_gl_context->MakeCurrent();
if (!InitializeGLExtensions(main_gl_context.get()) || !FillBackendInfo())
return false;

View File

@ -13,15 +13,7 @@
#include "VideoBackends/Software/SWTexture.h"
SWOGLWindow::SWOGLWindow() = default;
SWOGLWindow::~SWOGLWindow()
{
if (m_gl_context)
{
m_gl_context->ClearCurrent();
m_gl_context->Shutdown();
}
}
SWOGLWindow::~SWOGLWindow() = default;
std::unique_ptr<SWOGLWindow> SWOGLWindow::Create(const WindowSystemInfo& wsi)
{
@ -46,8 +38,6 @@ bool SWOGLWindow::Initialize(const WindowSystemInfo& wsi)
if (!m_gl_context)
return false;
m_gl_context->MakeCurrent();
// Init extension support.
if (!GLExtensions::Init(m_gl_context.get()))
{