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); glDeleteQueries(1, &query.handle);
} }
return GSRender::on_exit(); GSRender::on_exit();
} }
void GLGSRender::clear_surface(u32 arg) void GLGSRender::clear_surface(u32 arg)

View File

@ -4,16 +4,6 @@
#include "GSRender.h" #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() GSRender::GSRender()
{ {
m_frame = Emu.GetCallbacks().get_gs_frame().release(); m_frame = Emu.GetCallbacks().get_gs_frame().release();
@ -42,11 +32,22 @@ void GSRender::on_init_thread()
{ {
if (m_frame) if (m_frame)
{ {
m_context = m_frame->new_context(); m_context = m_frame->make_context();
m_frame->set_current(m_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) void GSRender::flip(int buffer)
{ {
if (m_frame) if (m_frame)

View File

@ -32,7 +32,7 @@ enum wm_event
using RSXDebuggerPrograms = std::vector<RSXDebuggerProgram>; using RSXDebuggerPrograms = std::vector<RSXDebuggerProgram>;
using draw_context_t = std::shared_ptr<void>; using draw_context_t = void*;
class GSFrameBase class GSFrameBase
{ {
@ -45,8 +45,8 @@ public:
virtual void hide() = 0; virtual void hide() = 0;
virtual void show() = 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 set_current(draw_context_t ctx) = 0;
virtual void flip(draw_context_t ctx, bool skip_frame=false) = 0; virtual void flip(draw_context_t ctx, bool skip_frame=false) = 0;
virtual int client_width() = 0; virtual int client_width() = 0;
@ -55,8 +55,6 @@ public:
virtual void* handle() const = 0; virtual void* handle() const = 0;
protected: protected:
virtual void delete_context(void* ctx) = 0;
virtual void* make_context() = 0;
//window manager event management //window manager event management
wm_event m_raised_event; wm_event m_raised_event;
@ -111,6 +109,7 @@ public:
void on_init_rsx() override; void on_init_rsx() override;
void on_init_thread() override; void on_init_thread() override;
void on_exit() override;
void flip(int buffer) 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); setFormat(m_format);
} }
void* gl_gs_frame::make_context() draw_context_t gl_gs_frame::make_context()
{ {
auto context = new QOpenGLContext(); auto context = new QOpenGLContext();
context->setFormat(m_format); context->setFormat(m_format);
@ -33,16 +33,18 @@ void* gl_gs_frame::make_context()
void gl_gs_frame::set_current(draw_context_t ctx) void gl_gs_frame::set_current(draw_context_t ctx)
{ {
if (!((QOpenGLContext*)ctx.get())->makeCurrent(this)) if (!((QOpenGLContext*)ctx)->makeCurrent(this))
{ {
create(); 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) 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 //Do not swap buffers if frame skip is active
if (skip_frame) return; if (skip_frame) return;
((QOpenGLContext*)context.get())->makeCurrent(this); ((QOpenGLContext*)context)->makeCurrent(this);
((QOpenGLContext*)context.get())->swapBuffers(this); ((QOpenGLContext*)context)->swapBuffers(this);
} }

View File

@ -11,8 +11,8 @@ private:
public: public:
gl_gs_frame(int w, int h, QIcon appIcon, bool disableMouse); 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 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; void flip(draw_context_t context, bool skip_frame=false) override;
}; };

View File

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

View File

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