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 isDrawing() const = 0;
|
||||||
virtual bool supportsShaders() const = 0;
|
virtual bool supportsShaders() const = 0;
|
||||||
virtual VideoShader* shaders() = 0;
|
virtual VideoShader* shaders() = 0;
|
||||||
virtual VideoProxy* videoProxy() { return nullptr; }
|
|
||||||
virtual int framebufferHandle() { return -1; }
|
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:
|
signals:
|
||||||
void showCursor();
|
void showCursor();
|
||||||
void hideCursor();
|
void hideCursor();
|
||||||
|
@ -88,6 +90,7 @@ private:
|
||||||
bool m_interframeBlending = false;
|
bool m_interframeBlending = false;
|
||||||
bool m_filter = false;
|
bool m_filter = false;
|
||||||
QTimer m_mouseTimer;
|
QTimer m_mouseTimer;
|
||||||
|
std::shared_ptr<VideoProxy> m_videoProxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent)
|
||||||
m_gl->create();
|
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
|
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->doneCurrent();
|
||||||
m_gl->moveToThread(m_drawThread);
|
m_gl->moveToThread(m_drawThread);
|
||||||
m_painter->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);
|
connect(m_drawThread, &QThread::started, m_painter, &PainterGL::start);
|
||||||
m_drawThread->start();
|
m_drawThread->start();
|
||||||
|
|
||||||
|
@ -217,21 +219,21 @@ void DisplayGL::resizePainter() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoProxy* DisplayGL::videoProxy() {
|
void DisplayGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) {
|
||||||
if (supportsShaders()) {
|
Display::setVideoProxy(proxy);
|
||||||
return &m_videoProxy;
|
if (m_drawThread && proxy) {
|
||||||
|
proxy->moveToThread(m_drawThread);
|
||||||
}
|
}
|
||||||
return nullptr;
|
m_painter->setVideoProxy(proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
int DisplayGL::framebufferHandle() {
|
int DisplayGL::framebufferHandle() {
|
||||||
return m_painter->glTex();
|
return m_painter->glTex();
|
||||||
}
|
}
|
||||||
|
|
||||||
PainterGL::PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent)
|
PainterGL::PainterGL(QWindow* surface, QOpenGLContext* parent)
|
||||||
: m_gl(parent)
|
: m_gl(parent)
|
||||||
, m_surface(surface)
|
, m_surface(surface)
|
||||||
, m_videoProxy(proxy)
|
|
||||||
{
|
{
|
||||||
#ifdef BUILD_GL
|
#ifdef BUILD_GL
|
||||||
mGLContext* glBackend;
|
mGLContext* glBackend;
|
||||||
|
@ -425,7 +427,9 @@ void PainterGL::stop() {
|
||||||
m_gl->moveToThread(m_surface->thread());
|
m_gl->moveToThread(m_surface->thread());
|
||||||
m_context.reset();
|
m_context.reset();
|
||||||
moveToThread(m_gl->thread());
|
moveToThread(m_gl->thread());
|
||||||
m_videoProxy->moveToThread(m_gl->thread());
|
if (m_videoProxy) {
|
||||||
|
m_videoProxy->moveToThread(m_gl->thread());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::pause() {
|
void PainterGL::pause() {
|
||||||
|
@ -516,6 +520,10 @@ void PainterGL::dequeueAll() {
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PainterGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) {
|
||||||
|
m_videoProxy = proxy;
|
||||||
|
}
|
||||||
|
|
||||||
void PainterGL::setShaders(struct VDir* dir) {
|
void PainterGL::setShaders(struct VDir* dir) {
|
||||||
if (!supportsShaders()) {
|
if (!supportsShaders()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -42,7 +42,7 @@ public:
|
||||||
bool isDrawing() const override { return m_isDrawing; }
|
bool isDrawing() const override { return m_isDrawing; }
|
||||||
bool supportsShaders() const override;
|
bool supportsShaders() const override;
|
||||||
VideoShader* shaders() override;
|
VideoShader* shaders() override;
|
||||||
VideoProxy* videoProxy() override;
|
void setVideoProxy(std::shared_ptr<VideoProxy>) override;
|
||||||
int framebufferHandle() override;
|
int framebufferHandle() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -71,14 +71,13 @@ private:
|
||||||
PainterGL* m_painter;
|
PainterGL* m_painter;
|
||||||
QThread* m_drawThread = nullptr;
|
QThread* m_drawThread = nullptr;
|
||||||
std::shared_ptr<CoreController> m_context;
|
std::shared_ptr<CoreController> m_context;
|
||||||
VideoProxy m_videoProxy;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PainterGL : public QObject {
|
class PainterGL : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PainterGL(VideoProxy* proxy, QWindow* surface, QOpenGLContext* parent);
|
PainterGL(QWindow* surface, QOpenGLContext* parent);
|
||||||
~PainterGL();
|
~PainterGL();
|
||||||
|
|
||||||
void setContext(std::shared_ptr<CoreController>);
|
void setContext(std::shared_ptr<CoreController>);
|
||||||
|
@ -87,6 +86,8 @@ public:
|
||||||
|
|
||||||
bool supportsShaders() const { return m_supportsShaders; }
|
bool supportsShaders() const { return m_supportsShaders; }
|
||||||
|
|
||||||
|
void setVideoProxy(std::shared_ptr<VideoProxy>);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void forceDraw();
|
void forceDraw();
|
||||||
void draw();
|
void draw();
|
||||||
|
@ -133,7 +134,7 @@ private:
|
||||||
QTimer m_swapTimer{this};
|
QTimer m_swapTimer{this};
|
||||||
bool m_needsUnlock = false;
|
bool m_needsUnlock = false;
|
||||||
bool m_frameReady = false;
|
bool m_frameReady = false;
|
||||||
VideoProxy* m_videoProxy;
|
std::shared_ptr<VideoProxy> m_videoProxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -780,7 +780,6 @@ void Window::gameStarted() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::gameStopped() {
|
void Window::gameStopped() {
|
||||||
m_controller.reset();
|
|
||||||
#ifdef M_CORE_GBA
|
#ifdef M_CORE_GBA
|
||||||
for (Action* action : m_platformActions) {
|
for (Action* action : m_platformActions) {
|
||||||
action->setEnabled(true);
|
action->setEnabled(true);
|
||||||
|
@ -816,6 +815,10 @@ void Window::gameStopped() {
|
||||||
m_audioProcessor.reset();
|
m_audioProcessor.reset();
|
||||||
}
|
}
|
||||||
m_display->stopDrawing();
|
m_display->stopDrawing();
|
||||||
|
|
||||||
|
m_controller.reset();
|
||||||
|
|
||||||
|
m_display->setVideoProxy({});
|
||||||
if (m_pendingClose) {
|
if (m_pendingClose) {
|
||||||
m_display.reset();
|
m_display.reset();
|
||||||
close();
|
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_config->getOption("hwaccelVideo").toInt() && m_display->supportsShaders() && controller->supportsFeature(CoreController::Feature::OPENGL)) {
|
||||||
if (m_display->videoProxy()) {
|
std::shared_ptr<VideoProxy> proxy = std::make_shared<VideoProxy>();
|
||||||
m_display->videoProxy()->attach(controller);
|
m_display->setVideoProxy(proxy);
|
||||||
}
|
proxy->attach(controller);
|
||||||
|
|
||||||
int fb = m_display->framebufferHandle();
|
int fb = m_display->framebufferHandle();
|
||||||
if (fb >= 0) {
|
if (fb >= 0) {
|
||||||
|
|
Loading…
Reference in New Issue