rsx: Rework context handling and stop leaking the GL ccontext

- GL contexts are external handles that require manual lifecycle management
This commit is contained in:
kd-11 2017-11-03 20:43:11 +03:00
parent 4ca98e53a6
commit 75504b3f5e
7 changed files with 34 additions and 31 deletions

View File

@ -836,7 +836,7 @@ void GLGSRender::on_exit()
glDeleteQueries(1, &query.handle);
}
return GSRender::on_exit();
GSRender::on_exit();
}
void GLGSRender::clear_surface(u32 arg)

View File

@ -4,16 +4,6 @@
#include "GSRender.h"
draw_context_t GSFrameBase::new_context()
{
if (void* context = make_context())
{
return std::shared_ptr<void>(context, [this](void* ctxt) { delete_context(ctxt); });
}
return nullptr;
}
GSRender::GSRender()
{
m_frame = Emu.GetCallbacks().get_gs_frame().release();
@ -42,11 +32,22 @@ void GSRender::on_init_thread()
{
if (m_frame)
{
m_context = m_frame->new_context();
m_context = m_frame->make_context();
m_frame->set_current(m_context);
}
}
void GSRender::on_exit()
{
if (m_frame)
{
m_frame->delete_context(m_context);
m_context = nullptr;
}
rsx::thread::on_exit();
}
void GSRender::flip(int buffer)
{
if (m_frame)

View File

@ -32,7 +32,7 @@ enum wm_event
using RSXDebuggerPrograms = std::vector<RSXDebuggerProgram>;
using draw_context_t = std::shared_ptr<void>;
using draw_context_t = void*;
class GSFrameBase
{
@ -45,8 +45,8 @@ public:
virtual void hide() = 0;
virtual void show() = 0;
draw_context_t new_context();
virtual void delete_context(draw_context_t ctx) = 0;
virtual draw_context_t make_context() = 0;
virtual void set_current(draw_context_t ctx) = 0;
virtual void flip(draw_context_t ctx, bool skip_frame=false) = 0;
virtual int client_width() = 0;
@ -55,8 +55,6 @@ public:
virtual void* handle() const = 0;
protected:
virtual void delete_context(void* ctx) = 0;
virtual void* make_context() = 0;
//window manager event management
wm_event m_raised_event;
@ -111,6 +109,7 @@ public:
void on_init_rsx() override;
void on_init_thread() override;
void on_exit() override;
void flip(int buffer) override;
};

View File

@ -22,7 +22,7 @@ gl_gs_frame::gl_gs_frame(int w, int h, QIcon appIcon, bool disableMouse)
setFormat(m_format);
}
void* gl_gs_frame::make_context()
draw_context_t gl_gs_frame::make_context()
{
auto context = new QOpenGLContext();
context->setFormat(m_format);
@ -33,16 +33,18 @@ void* gl_gs_frame::make_context()
void gl_gs_frame::set_current(draw_context_t ctx)
{
if (!((QOpenGLContext*)ctx.get())->makeCurrent(this))
if (!((QOpenGLContext*)ctx)->makeCurrent(this))
{
create();
((QOpenGLContext*)ctx.get())->makeCurrent(this);
((QOpenGLContext*)ctx)->makeCurrent(this);
}
}
void gl_gs_frame::delete_context(void* ctx)
void gl_gs_frame::delete_context(draw_context_t ctx)
{
((QOpenGLContext*)ctx)->deleteLater();
auto gl_ctx = (QOpenGLContext*)ctx;
gl_ctx->doneCurrent();
delete gl_ctx;
}
void gl_gs_frame::flip(draw_context_t context, bool skip_frame)
@ -52,6 +54,6 @@ void gl_gs_frame::flip(draw_context_t context, bool skip_frame)
//Do not swap buffers if frame skip is active
if (skip_frame) return;
((QOpenGLContext*)context.get())->makeCurrent(this);
((QOpenGLContext*)context.get())->swapBuffers(this);
((QOpenGLContext*)context)->makeCurrent(this);
((QOpenGLContext*)context)->swapBuffers(this);
}

View File

@ -11,8 +11,8 @@ private:
public:
gl_gs_frame(int w, int h, QIcon appIcon, bool disableMouse);
void* make_context() override;
draw_context_t make_context() override;
void set_current(draw_context_t context) override;
void delete_context(void* context) override;
void delete_context(draw_context_t context) override;
void flip(draw_context_t context, bool skip_frame=false) override;
};

View File

@ -154,7 +154,7 @@ void* gs_frame::handle() const
#endif
}
void* gs_frame::make_context()
draw_context_t gs_frame::make_context()
{
return nullptr;
}
@ -164,7 +164,7 @@ void gs_frame::set_current(draw_context_t ctx)
Q_UNUSED(ctx);
}
void gs_frame::delete_context(void* ctx)
void gs_frame::delete_context(draw_context_t ctx)
{
Q_UNUSED(ctx);
}

View File

@ -22,6 +22,10 @@ class gs_frame : public QWindow, public GSFrameBase
public:
gs_frame(const QString& title, int w, int h, QIcon appIcon, bool disableMouse);
draw_context_t make_context() override;
void set_current(draw_context_t context) override;
void delete_context(draw_context_t context) override;
wm_event get_default_wm_event() const override;
protected:
virtual void paintEvent(QPaintEvent *event);
@ -38,9 +42,6 @@ protected:
void* handle() const override;
void* make_context() override;
void set_current(draw_context_t context) override;
void delete_context(void* context) override;
void flip(draw_context_t context, bool skip_frame=false) override;
int client_width() override;
int client_height() override;