mirror of https://github.com/mgba-emu/mgba.git
Qt: Fix VideoProxy lifetime
This commit is contained in:
parent
33d13b3757
commit
fcb5a4168f
|
@ -49,9 +49,11 @@ public:
|
|||
virtual bool isDrawing() const = 0;
|
||||
virtual bool supportsShaders() const = 0;
|
||||
virtual VideoShader* shaders() = 0;
|
||||
virtual VideoProxy* videoProxy() { return nullptr; }
|
||||
virtual int framebufferHandle() { return -1; }
|
||||
|
||||
virtual void setVideoProxy(std::shared_ptr<VideoProxy> proxy) { m_videoProxy = proxy; }
|
||||
std::shared_ptr<VideoProxy> videoProxy() { return m_videoProxy; }
|
||||
|
||||
signals:
|
||||
void showCursor();
|
||||
void hideCursor();
|
||||
|
@ -88,6 +90,7 @@ private:
|
|||
bool m_interframeBlending = false;
|
||||
bool m_filter = false;
|
||||
QTimer m_mouseTimer;
|
||||
std::shared_ptr<VideoProxy> m_videoProxy;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent)
|
|||
m_gl->create();
|
||||
}
|
||||
|
||||
m_painter = new PainterGL(&m_videoProxy, windowHandle(), m_gl);
|
||||
m_painter = new PainterGL(windowHandle(), m_gl);
|
||||
setUpdatesEnabled(false); // Prevent paint events, which can cause race conditions
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,9 @@ void DisplayGL::startDrawing(std::shared_ptr<CoreController> controller) {
|
|||
m_gl->doneCurrent();
|
||||
m_gl->moveToThread(m_drawThread);
|
||||
m_painter->moveToThread(m_drawThread);
|
||||
m_videoProxy.moveToThread(m_drawThread);
|
||||
if (videoProxy()) {
|
||||
videoProxy()->moveToThread(m_drawThread);
|
||||
}
|
||||
connect(m_drawThread, &QThread::started, m_painter, &PainterGL::start);
|
||||
m_drawThread->start();
|
||||
|
||||
|
@ -217,21 +219,21 @@ void DisplayGL::resizePainter() {
|
|||
}
|
||||
}
|
||||
|
||||
VideoProxy* DisplayGL::videoProxy() {
|
||||
if (supportsShaders()) {
|
||||
return &m_videoProxy;
|
||||
void DisplayGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) {
|
||||
Display::setVideoProxy(proxy);
|
||||
if (m_drawThread && proxy) {
|
||||
proxy->moveToThread(m_drawThread);
|
||||
}
|
||||
return nullptr;
|
||||
m_painter->setVideoProxy(proxy);
|
||||
}
|
||||
|
||||
int DisplayGL::framebufferHandle() {
|
||||
return m_painter->glTex();
|
||||
}
|
||||
|
||||
PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent)
|
||||
PainterGL::PainterGL(QWindow* surface, QOpenGLContext* parent)
|
||||
: m_gl(parent)
|
||||
, m_surface(surface)
|
||||
, m_videoProxy(proxy)
|
||||
{
|
||||
#ifdef BUILD_GL
|
||||
mGLContext* glBackend;
|
||||
|
@ -425,7 +427,9 @@ void PainterGL::stop() {
|
|||
m_gl->moveToThread(m_surface->thread());
|
||||
m_context.reset();
|
||||
moveToThread(m_gl->thread());
|
||||
m_videoProxy->moveToThread(m_gl->thread());
|
||||
if (m_videoProxy) {
|
||||
m_videoProxy->moveToThread(m_gl->thread());
|
||||
}
|
||||
}
|
||||
|
||||
void PainterGL::pause() {
|
||||
|
@ -516,6 +520,10 @@ void PainterGL::dequeueAll() {
|
|||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
void PainterGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) {
|
||||
m_videoProxy = proxy;
|
||||
}
|
||||
|
||||
void PainterGL::setShaders(struct VDir* dir) {
|
||||
if (!supportsShaders()) {
|
||||
return;
|
||||
|
|
|
@ -42,7 +42,7 @@ public:
|
|||
bool isDrawing() const override { return m_isDrawing; }
|
||||
bool supportsShaders() const override;
|
||||
VideoShader* shaders() override;
|
||||
VideoProxy* videoProxy() override;
|
||||
void setVideoProxy(std::shared_ptr<VideoProxy>) override;
|
||||
int framebufferHandle() override;
|
||||
|
||||
public slots:
|
||||
|
@ -71,14 +71,13 @@ private:
|
|||
PainterGL* m_painter;
|
||||
QThread* m_drawThread = nullptr;
|
||||
std::shared_ptr<CoreController> m_context;
|
||||
VideoProxy m_videoProxy;
|
||||
};
|
||||
|
||||
class PainterGL : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent);
|
||||
PainterGL(QWindow* surface, QOpenGLContext* parent);
|
||||
~PainterGL();
|
||||
|
||||
void setContext(std::shared_ptr<CoreController>);
|
||||
|
@ -87,6 +86,8 @@ public:
|
|||
|
||||
bool supportsShaders() const { return m_supportsShaders; }
|
||||
|
||||
void setVideoProxy(std::shared_ptr<VideoProxy>);
|
||||
|
||||
public slots:
|
||||
void forceDraw();
|
||||
void draw();
|
||||
|
@ -133,7 +134,7 @@ private:
|
|||
QTimer m_swapTimer{this};
|
||||
bool m_needsUnlock = false;
|
||||
bool m_frameReady = false;
|
||||
VideoProxy* m_videoProxy;
|
||||
std::shared_ptr<VideoProxy> m_videoProxy;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -780,7 +780,6 @@ void Window::gameStarted() {
|
|||
}
|
||||
|
||||
void Window::gameStopped() {
|
||||
m_controller.reset();
|
||||
#ifdef M_CORE_GBA
|
||||
for (Action* action : m_platformActions) {
|
||||
action->setEnabled(true);
|
||||
|
@ -816,6 +815,10 @@ void Window::gameStopped() {
|
|||
m_audioProcessor.reset();
|
||||
}
|
||||
m_display->stopDrawing();
|
||||
|
||||
m_controller.reset();
|
||||
|
||||
m_display->setVideoProxy({});
|
||||
if (m_pendingClose) {
|
||||
m_display.reset();
|
||||
close();
|
||||
|
@ -1739,9 +1742,9 @@ void Window::setController(CoreController* controller, const QString& fname) {
|
|||
}
|
||||
|
||||
if (m_config->getOption("hwaccelVideo").toInt() && m_display->supportsShaders() && controller->supportsFeature(CoreController::Feature::OPENGL)) {
|
||||
if (m_display->videoProxy()) {
|
||||
m_display->videoProxy()->attach(controller);
|
||||
}
|
||||
std::shared_ptr<VideoProxy> proxy = std::make_shared<VideoProxy>();
|
||||
m_display->setVideoProxy(proxy);
|
||||
proxy->attach(controller);
|
||||
|
||||
int fb = m_display->framebufferHandle();
|
||||
if (fb >= 0) {
|
||||
|
|
Loading…
Reference in New Issue