all repos — mgba @ fcb5a4168fed46dffb4572d193182d6b25d71b39

mGBA Game Boy Advance Emulator

Qt: Fix VideoProxy lifetime
Vicki Pfau vi@endrift.com
Tue, 28 May 2019 21:52:15 -0700
commit

fcb5a4168fed46dffb4572d193182d6b25d71b39

parent

33d13b3757da9ec8ebecfa3a684e6ddd3d4b53e1

M src/platform/qt/Display.hsrc/platform/qt/Display.h

@@ -49,9 +49,11 @@ virtual void startDrawing(std::shared_ptr<CoreController>) = 0;

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 @@ bool m_lockIntegerScaling = false;

bool m_interframeBlending = false; bool m_filter = false; QTimer m_mouseTimer; + std::shared_ptr<VideoProxy> m_videoProxy; }; }
M src/platform/qt/DisplayGL.cppsrc/platform/qt/DisplayGL.cpp

@@ -57,7 +57,7 @@ m_gl->setFormat(newFormat);

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 @@ m_drawThread->setObjectName("Painter Thread");

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 @@ QMetaObject::invokeMethod(m_painter, "resize", Qt::BlockingQueuedConnection, Q_ARG(QSize, size()));

} } -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 @@ m_gl->doneCurrent();

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() {

@@ -514,6 +518,10 @@ if (buffer) {

m_backend->postFrame(m_backend, buffer); } m_mutex.unlock(); +} + +void PainterGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) { + m_videoProxy = proxy; } void PainterGL::setShaders(struct VDir* dir) {
M src/platform/qt/DisplayGL.hsrc/platform/qt/DisplayGL.h

@@ -42,7 +42,7 @@ void startDrawing(std::shared_ptr<CoreController>) override;

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 @@ QOpenGLContext* m_gl;

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>);

@@ -86,6 +85,8 @@ void setMessagePainter(MessagePainter*);

void enqueue(const uint32_t* backing); bool supportsShaders() const { return m_supportsShaders; } + + void setVideoProxy(std::shared_ptr<VideoProxy>); public slots: void forceDraw();

@@ -133,7 +134,7 @@ MessagePainter* m_messagePainter = nullptr;

QTimer m_swapTimer{this}; bool m_needsUnlock = false; bool m_frameReady = false; - VideoProxy* m_videoProxy; + std::shared_ptr<VideoProxy> m_videoProxy; }; }
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -780,7 +780,6 @@ #endif

} void Window::gameStopped() { - m_controller.reset(); #ifdef M_CORE_GBA for (Action* action : m_platformActions) { action->setEnabled(true);

@@ -816,6 +815,10 @@ m_audioProcessor->stop();

m_audioProcessor.reset(); } m_display->stopDrawing(); + + m_controller.reset(); + + m_display->setVideoProxy({}); if (m_pendingClose) { m_display.reset(); close();

@@ -1739,9 +1742,9 @@ reloadDisplayDriver();

} 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) {