From 2f2287683ab038a1d6df0dc7948a1f1d348dd585 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 18 Apr 2023 20:15:57 -0700 Subject: [PATCH] Qt: Rip out OpenGL proxy thread --- src/platform/qt/DisplayGL.cpp | 154 +++++----------------------------- src/platform/qt/DisplayGL.h | 20 ----- 2 files changed, 20 insertions(+), 154 deletions(-) diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index 3ac10042b..ff60ea50e 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -63,11 +63,6 @@ typedef struct _XDisplay Display; using namespace QGBA; -enum ThreadStartFrom { - START = 1, - PROXY = 2, -}; - QHash DisplayGL::s_supports; uint qHash(const QSurfaceFormat& format, uint seed) { @@ -221,11 +216,6 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) m_drawThread.setObjectName("Painter Thread"); m_painter->setThread(&m_drawThread); - m_proxyThread.setObjectName("OpenGL Proxy Thread"); - m_proxyContext = std::make_unique(); - m_proxyContext->setFormat(format); - connect(m_painter.get(), &PainterGL::created, this, &DisplayGL::setupProxyThread); - connect(&m_drawThread, &QThread::started, m_painter.get(), &PainterGL::create); connect(m_painter.get(), &PainterGL::started, this, [this] { m_hasStarted = true; @@ -240,11 +230,6 @@ DisplayGL::~DisplayGL() { QMetaObject::invokeMethod(m_painter.get(), "destroy", Qt::BlockingQueuedConnection); m_drawThread.exit(); m_drawThread.wait(); - - if (m_proxyThread.isRunning()) { - m_proxyThread.exit(); - m_proxyThread.wait(); - } } bool DisplayGL::supportsShaders() const { @@ -265,6 +250,9 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { m_painter->setContext(controller); m_painter->setMessagePainter(messagePainter()); m_context = controller; + if (videoProxy()) { + videoProxy()->moveToThread(&m_drawThread); + } lockAspectRatio(isAspectRatioLocked()); lockIntegerScaling(isIntegerScalingLocked()); @@ -279,15 +267,6 @@ void DisplayGL::startDrawing(std::shared_ptr controller) { messagePainter()->resize(size(), devicePixelRatio()); #endif - startThread(ThreadStartFrom::START); -} - -void DisplayGL::startThread(int from) { - m_threadStartPending |= from; - if (m_threadStartPending < 3) { - return; - } - CoreController::Interrupter interrupter(m_context); QMetaObject::invokeMethod(m_painter.get(), "start"); if (!m_gl) { @@ -363,7 +342,6 @@ void DisplayGL::stopDrawing() { hide(); } setUpdatesEnabled(true); - m_threadStartPending &= ~1; } m_context.reset(); } @@ -481,35 +459,11 @@ bool DisplayGL::shouldDisableUpdates() { void DisplayGL::setVideoProxy(std::shared_ptr proxy) { Display::setVideoProxy(proxy); if (proxy) { - proxy->moveToThread(&m_proxyThread); + proxy->moveToThread(&m_drawThread); } m_painter->setVideoProxy(proxy); } -void DisplayGL::setupProxyThread() { - m_proxyContext->moveToThread(&m_proxyThread); - m_proxySurface.create(); - connect(&m_proxyThread, &QThread::started, m_proxyContext.get(), [this]() { - m_proxyContext->setShareContext(m_painter->shareContext()); - m_proxyContext->create(); - m_proxyContext->makeCurrent(&m_proxySurface); -#if defined(_WIN32) && defined(USE_EPOXY) - epoxy_handle_external_wglMakeCurrent(); -#endif - QMetaObject::invokeMethod(this, "startThread", Q_ARG(int, ThreadStartFrom::PROXY)); - }); - connect(m_painter.get(), &PainterGL::texSwapped, m_proxyContext.get(), [this]() { - if (!m_context->hardwareAccelerated()) { - return; - } - if (videoProxy()) { - videoProxy()->processData(); - } - m_painter->updateFramebufferHandle(); - }, Qt::BlockingQueuedConnection); - m_proxyThread.start(); -} - int DisplayGL::framebufferHandle() { return m_painter->glTex(); } @@ -580,12 +534,6 @@ void PainterGL::create() { gl2Backend = static_cast(malloc(sizeof(mGLES2Context))); mGLES2ContextCreate(gl2Backend); m_backend = &gl2Backend->d; - QOpenGLFunctions* fn = m_gl->functions(); - fn->glGenTextures(m_bridgeTexes.size(), m_bridgeTexes.data()); - for (auto tex : m_bridgeTexes) { - m_freeTex.enqueue(tex); - } - m_bridgeTexIn = m_freeTex.dequeue(); } #endif @@ -653,11 +601,9 @@ void PainterGL::destroy() { } makeCurrent(); #if defined(BUILD_GLES2) || defined(BUILD_GLES3) - QOpenGLFunctions* fn = m_gl->functions(); if (m_shader.passes) { mGLES2ShaderFree(&m_shader); } - fn->glDeleteTextures(m_bridgeTexes.size(), m_bridgeTexes.data()); #endif m_backend->deinit(m_backend); m_gl->doneCurrent(); @@ -783,7 +729,6 @@ void PainterGL::start() { } #endif resizeContext(); - m_context->addFrameAction(std::bind(&PainterGL::swapTex, this)); m_buffer = nullptr; m_active = true; @@ -792,7 +737,7 @@ void PainterGL::start() { } void PainterGL::draw() { - if (!m_started || (m_queue.isEmpty() && m_queueTex.isEmpty())) { + if (!m_started || m_queue.isEmpty()) { return; } @@ -878,6 +823,11 @@ void PainterGL::doStop() { } m_backend->clear(m_backend); m_backend->swap(m_backend); + if (m_videoProxy) { + m_videoProxy->reset(); + m_videoProxy->moveToThread(m_window->thread()); + m_videoProxy.reset(); + } } void PainterGL::pause() { @@ -905,33 +855,22 @@ void PainterGL::performDraw() { } void PainterGL::enqueue(const uint32_t* backing) { - if (!backing) { - return; - } QMutexLocker locker(&m_mutex); uint32_t* buffer = nullptr; - if (m_free.isEmpty()) { - buffer = m_queue.dequeue(); - } else { - buffer = m_free.takeLast(); - } - if (buffer) { - QSize size = m_context->screenDimensions(); - memcpy(buffer, backing, size.width() * size.height() * BYTES_PER_PIXEL); + if (backing) { + if (m_free.isEmpty()) { + buffer = m_queue.dequeue(); + } else { + buffer = m_free.takeLast(); + } + if (buffer) { + QSize size = m_context->screenDimensions(); + memcpy(buffer, backing, size.width() * size.height() * BYTES_PER_PIXEL); + } } m_queue.enqueue(buffer); } -void PainterGL::enqueue(GLuint tex) { - QMutexLocker locker(&m_mutex); - if (m_freeTex.isEmpty()) { - m_bridgeTexIn = m_queueTex.dequeue(); - } else { - m_bridgeTexIn = m_freeTex.takeLast(); - } - m_queueTex.enqueue(tex); -} - void PainterGL::dequeue() { QMutexLocker locker(&m_mutex); if (!m_queue.isEmpty()) { @@ -941,19 +880,6 @@ void PainterGL::dequeue() { } m_buffer = buffer; } - - if (!m_queueTex.isEmpty()) { - if (m_bridgeTexOut != std::numeric_limits::max()) { - m_freeTex.enqueue(m_bridgeTexOut); - } - m_bridgeTexOut = m_queueTex.dequeue(); -#if defined(BUILD_GLES2) || defined(BUILD_GLES3) - if (supportsShaders()) { - mGLES2Context* gl2Backend = reinterpret_cast(m_backend); - gl2Backend->tex = m_bridgeTexOut; - } -#endif - } } void PainterGL::dequeueAll(bool keep) { @@ -974,19 +900,6 @@ void PainterGL::dequeueAll(bool keep) { m_free.append(m_buffer); m_buffer = nullptr; } - - m_queueTex.clear(); - m_freeTex.clear(); - for (auto tex : m_bridgeTexes) { - if (keep && tex == m_bridgeTexIn) { - continue; - } - m_freeTex.enqueue(tex); - } - if (!keep) { - m_bridgeTexIn = m_freeTex.dequeue(); - m_bridgeTexOut = std::numeric_limits::max(); - } } void PainterGL::setVideoProxy(std::shared_ptr proxy) { @@ -1067,31 +980,4 @@ QOpenGLContext* PainterGL::shareContext() { } } -void PainterGL::updateFramebufferHandle() { - QOpenGLFunctions* fn = m_gl->functions(); - // TODO: Figure out why glFlush doesn't work here on Intel/Windows - if (glContextHasBug(OpenGLBug::CROSS_THREAD_FLUSH)) { - fn->glFinish(); - } else { - fn->glFlush(); - } - - CoreController::Interrupter interrupter(m_context); - if (!m_context->hardwareAccelerated()) { - return; - } - enqueue(m_bridgeTexIn); - m_context->setFramebufferHandle(m_bridgeTexIn); -} - -void PainterGL::swapTex() { - if (!m_started) { - return; - } - - CoreController::Interrupter interrupter(m_context); - emit texSwapped(); - m_context->addFrameAction(std::bind(&PainterGL::swapTex, this)); -} - #endif diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index b5b9b9ebd..d0fead16f 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -119,10 +119,6 @@ protected: virtual void paintEvent(QPaintEvent*) override { forceDraw(); } virtual void resizeEvent(QResizeEvent*) override; -private slots: - void startThread(int); - void setupProxyThread(); - private: void resizePainter(); bool shouldDisableUpdates(); @@ -131,14 +127,10 @@ private: bool m_isDrawing = false; bool m_hasStarted = false; - int m_threadStartPending = 0; std::unique_ptr m_painter; QThread m_drawThread; - QThread m_proxyThread; std::shared_ptr m_context; mGLWidget* m_gl; - QOffscreenSurface m_proxySurface; - std::unique_ptr m_proxyContext; }; class PainterGL : public QObject { @@ -152,7 +144,6 @@ public: void setContext(std::shared_ptr); void setMessagePainter(MessagePainter*); void enqueue(const uint32_t* backing); - void enqueue(GLuint tex); void stop(); @@ -164,9 +155,6 @@ public: void setVideoProxy(std::shared_ptr); void interrupt(); - // Run on main thread - void swapTex(); - public slots: void create(); void destroy(); @@ -185,7 +173,6 @@ public slots: void filter(bool filter); void swapInterval(int interval); void resizeContext(); - void updateFramebufferHandle(); void setShaders(struct VDir*); void clearShaders(); @@ -210,13 +197,6 @@ private: QQueue m_queue; uint32_t* m_buffer = nullptr; - std::array m_bridgeTexes; - QQueue m_freeTex; - QQueue m_queueTex; - - GLuint m_bridgeTexIn = std::numeric_limits::max(); - GLuint m_bridgeTexOut = std::numeric_limits::max(); - QPainter m_painter; QMutex m_mutex; QWindow* m_window;