Permalink
Browse files

GLContext: Use destructor instead of Shutdown() to cleanup

Also uses the Initialize() method to make the context current.
  • Loading branch information...
stenzek committed Oct 3, 2018
1 parent 4b8d1c2 commit 025e909773a2761cad8a3954498fe800f6f94963
@@ -50,10 +50,6 @@ bool GLContext::ClearCurrent()
return false;
}
void GLContext::Shutdown()
{
}
void GLContext::Update()
{
}
@@ -31,7 +31,6 @@ class GLContext
virtual bool IsHeadless() const;
virtual std::unique_ptr<GLContext> CreateSharedContext();
virtual void Shutdown();
virtual bool MakeCurrent();
virtual bool ClearCurrent();
@@ -44,7 +43,8 @@ class GLContext
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 @@ class GLContext
// Window dimensions.
u32 m_backbuffer_width = 0;
u32 m_backbuffer_height = 0;
bool m_is_core_context = false;
bool m_is_shared = false;
};
@@ -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;
@@ -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 @@ static bool AttachContextToView(NSOpenGLContext* context, NSView* view, u32* wid
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 @@ static bool AttachContextToView(NSOpenGLContext* context, NSView* view, u32* wid
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 @@ static bool AttachContextToView(NSOpenGLContext* context, NSView* view, u32* wid
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)
@@ -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;
}
@@ -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 @@ class GLContextEGL : public GLContext
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 @@ class GLContextEGL : public GLContext
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;
};
@@ -6,7 +6,7 @@
#include "Common/GL/GLInterface/EGL.h"
class GLContextEGLAndroid : public GLContextEGL
class GLContextEGLAndroid final : public GLContextEGL
{
protected:
EGLDisplay OpenEGLDisplay() override;
@@ -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()
{
@@ -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;
@@ -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();
@@ -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 @@ class GLContextGLX : public GLContext
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;
Oops, something went wrong.

0 comments on commit 025e909

Please sign in to comment.