From 5b52f0f27750158a859bcca4d0fae0d0ee371a70 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 17 Mar 2023 02:29:47 -0700 Subject: [PATCH] Qt: Fix OSD on modern macOS (fixes #2736) --- CHANGES | 1 + src/platform/qt/DisplayGL.cpp | 39 +++++++++++++++++++++++++++++++---- src/platform/qt/DisplayGL.h | 6 ++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 286e56790..48d6756c0 100644 --- a/CHANGES +++ b/CHANGES @@ -17,6 +17,7 @@ Other fixes: - Qt: Fix full-buffer rewind - Qt: Fix crash if loading a shader fails - Qt: Fix black screen when starting with a game (fixes mgba.io/i/2781) + - Qt: Fix OSD on modern macOS (fixes mgba.io/i/2736) - Scripting: Fix receiving packets for client sockets - Scripting: Fix empty receive calls returning unknown error on Windows Misc: diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index acc001f9a..9d93a6b57 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -70,6 +70,10 @@ mGLWidget::mGLWidget(QWidget* parent) connect(&m_refresh, &QTimer::timeout, this, static_cast(&QWidget::update)); } +mGLWidget::~mGLWidget() { + // This is needed for unique_ptr to work +} + void mGLWidget::initializeGL() { m_vao = std::make_unique(); m_vao->create(); @@ -99,6 +103,8 @@ void mGLWidget::initializeGL() { m_vaoDone = false; m_tex = 0; + + m_paintDev = std::make_unique(); } bool mGLWidget::finalizeVAO() { @@ -150,6 +156,23 @@ void mGLWidget::paintGL() { } else { m_refresh.start(17); } + + if (m_showOSD && m_messagePainter) { + qreal r = window()->devicePixelRatio(); + m_paintDev->setDevicePixelRatio(r); + m_paintDev->setSize(size() * r); + QPainter painter(m_paintDev.get()); + m_messagePainter->paint(&painter); + painter.end(); + } +} + +void mGLWidget::setMessagePainter(MessagePainter* messagePainter) { + m_messagePainter = messagePainter; +} + +void mGLWidget::setShowOSD(bool showOSD) { + m_showOSD = showOSD; } DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) @@ -170,6 +193,7 @@ DisplayGL::DisplayGL(const QSurfaceFormat& format, QWidget* parent) m_gl = new mGLWidget; m_gl->setAttribute(Qt::WA_NativeWindow); m_gl->setFormat(format); + m_gl->setMessagePainter(messagePainter()); QBoxLayout* layout = new QVBoxLayout; layout->addWidget(m_gl); layout->setContentsMargins(0, 0, 0, 0); @@ -372,6 +396,9 @@ void DisplayGL::interframeBlending(bool enable) { void DisplayGL::showOSDMessages(bool enable) { Display::showOSDMessages(enable); + if (m_gl) { + m_gl->setShowOSD(enable); + } QMetaObject::invokeMethod(m_painter.get(), "showOSD", Q_ARG(bool, enable)); } @@ -525,7 +552,9 @@ void PainterGL::create() { mGLES2Context* gl2Backend; #endif - m_paintDev = std::make_unique(); + if (!m_widget) { + m_paintDev = std::make_unique(); + } #if defined(BUILD_GLES2) || defined(BUILD_GLES3) if (m_supportsShaders) { @@ -650,8 +679,10 @@ void PainterGL::setMessagePainter(MessagePainter* messagePainter) { void PainterGL::resize(const QSize& size) { qreal r = m_window->devicePixelRatio(); m_size = size; - m_paintDev->setSize(m_size * r); - m_paintDev->setDevicePixelRatio(r); + if (m_paintDev) { + m_paintDev->setSize(m_size * r); + m_paintDev->setDevicePixelRatio(r); + } if (m_started && !m_active) { forceDraw(); } @@ -818,7 +849,7 @@ void PainterGL::performDraw() { m_backend->postFrame(m_backend, m_buffer); } m_backend->drawFrame(m_backend); - if (m_showOSD && m_messagePainter && !glContextHasBug(OpenGLBug::IG4ICD_CRASH)) { + if (m_showOSD && m_messagePainter && m_paintDev && !glContextHasBug(OpenGLBug::IG4ICD_CRASH)) { m_painter.begin(m_paintDev.get()); m_messagePainter->paint(&m_painter); m_painter.end(); diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index a0c0c17d4..129d8adc4 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -51,9 +51,12 @@ Q_OBJECT public: mGLWidget(QWidget* parent = nullptr); + ~mGLWidget(); void setTex(GLuint tex) { m_tex = tex; } void setVBO(GLuint vbo) { m_vbo = vbo; } + void setMessagePainter(MessagePainter*); + void setShowOSD(bool showOSD); bool finalizeVAO(); void reset(); @@ -72,6 +75,9 @@ private: QTimer m_refresh; int m_refreshResidue = 0; + std::unique_ptr m_paintDev; + MessagePainter* m_messagePainter = nullptr; + bool m_showOSD = false; }; class PainterGL;