diff --git a/src/platform/qt/Display.cpp b/src/platform/qt/Display.cpp index 59d218d46..1e1089d8f 100644 --- a/src/platform/qt/Display.cpp +++ b/src/platform/qt/Display.cpp @@ -50,3 +50,20 @@ Display::Display(QWidget* parent) setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); } + +void Display::resizeEvent(QResizeEvent*) { + m_messagePainter.resize(size(), m_lockAspectRatio); +} + +void Display::lockAspectRatio(bool lock) { + m_lockAspectRatio = lock; + m_messagePainter.resize(size(), m_lockAspectRatio); +} + +void Display::filter(bool filter) { + m_filter = filter; +} + +void Display::showMessage(const QString& message) { + m_messagePainter.showMessage(message); +} diff --git a/src/platform/qt/Display.h b/src/platform/qt/Display.h index c69461f39..6ae6a35c2 100644 --- a/src/platform/qt/Display.h +++ b/src/platform/qt/Display.h @@ -8,6 +8,8 @@ #include +#include "MessagePainter.h" + struct GBAThread; namespace QGBA { @@ -28,20 +30,32 @@ public: static Display* create(QWidget* parent = nullptr); static void setDriver(Driver driver) { s_driver = driver; } + bool isAspectRatioLocked() const { return m_lockAspectRatio; } + bool isFiltered() const { return m_filter; } + public slots: virtual void startDrawing(GBAThread* context) = 0; virtual void stopDrawing() = 0; virtual void pauseDrawing() = 0; virtual void unpauseDrawing() = 0; virtual void forceDraw() = 0; - virtual void lockAspectRatio(bool lock) = 0; - virtual void filter(bool filter) = 0; + virtual void lockAspectRatio(bool lock); + virtual void filter(bool filter); virtual void framePosted(const uint32_t*) = 0; - virtual void showMessage(const QString& message) = 0; + void showMessage(const QString& message); + +protected: + void resizeEvent(QResizeEvent*); + + MessagePainter* messagePainter() { return &m_messagePainter; } private: static Driver s_driver; + + MessagePainter m_messagePainter; + bool m_lockAspectRatio; + bool m_filter; }; } diff --git a/src/platform/qt/DisplayGL.cpp b/src/platform/qt/DisplayGL.cpp index f861387c6..2308a7d9c 100644 --- a/src/platform/qt/DisplayGL.cpp +++ b/src/platform/qt/DisplayGL.cpp @@ -19,8 +19,6 @@ DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent) , m_gl(new EmptyGLWidget(format, this)) , m_painter(new PainterGL(m_gl)) , m_drawThread(nullptr) - , m_lockAspectRatio(false) - , m_filter(false) , m_context(nullptr) { } @@ -34,6 +32,7 @@ void DisplayGL::startDrawing(GBAThread* thread) { return; } m_painter->setContext(thread); + m_painter->setMessagePainter(messagePainter()); m_context = thread; m_painter->resize(size()); m_gl->move(0, 0); @@ -46,8 +45,8 @@ void DisplayGL::startDrawing(GBAThread* thread) { m_drawThread->start(); GBASyncSetVideoSync(&m_context->sync, false); - lockAspectRatio(m_lockAspectRatio); - filter(m_filter); + lockAspectRatio(isAspectRatioLocked()); + filter(isFiltered()); resizePainter(); } @@ -96,14 +95,14 @@ void DisplayGL::forceDraw() { } void DisplayGL::lockAspectRatio(bool lock) { - m_lockAspectRatio = lock; + Display::lockAspectRatio(lock); if (m_drawThread) { QMetaObject::invokeMethod(m_painter, "lockAspectRatio", Q_ARG(bool, lock)); } } void DisplayGL::filter(bool filter) { - m_filter = filter; + Display::filter(filter); if (m_drawThread) { QMetaObject::invokeMethod(m_painter, "filter", Q_ARG(bool, filter)); } @@ -115,13 +114,8 @@ void DisplayGL::framePosted(const uint32_t* buffer) { } } -void DisplayGL::showMessage(const QString& message) { - if (m_drawThread) { - QMetaObject::invokeMethod(m_painter, "showMessage", Qt::BlockingQueuedConnection, Q_ARG(const QString&, message)); - } -} - -void DisplayGL::resizeEvent(QResizeEvent*) { +void DisplayGL::resizeEvent(QResizeEvent* event) { + Display::resizeEvent(event); resizePainter(); } @@ -152,6 +146,10 @@ void PainterGL::setContext(GBAThread* context) { m_context = context; } +void PainterGL::setMessagePainter(MessagePainter* messagePainter) { + m_messagePainter = messagePainter; +} + void PainterGL::setBacking(const uint32_t* backing) { m_gl->makeCurrent(); m_backend.d.postFrame(&m_backend.d, backing); @@ -164,7 +162,6 @@ void PainterGL::setBacking(const uint32_t* backing) { void PainterGL::resize(const QSize& size) { m_size = size; if (m_active) { - m_messagePainter->resize(size, m_backend.d.lockAspectRatio); forceDraw(); } } @@ -172,7 +169,6 @@ void PainterGL::resize(const QSize& size) { void PainterGL::lockAspectRatio(bool lock) { m_backend.d.lockAspectRatio = lock; if (m_active) { - m_messagePainter->resize(m_size, m_backend.d.lockAspectRatio); forceDraw(); } } @@ -185,8 +181,6 @@ void PainterGL::filter(bool filter) { } void PainterGL::start() { - m_messagePainter = new MessagePainter(this); - m_messagePainter->resize(m_size, m_backend.d.lockAspectRatio); m_gl->makeCurrent(); m_backend.d.init(&m_backend.d, reinterpret_cast(m_gl->winId())); m_gl->doneCurrent(); @@ -220,9 +214,6 @@ void PainterGL::stop() { m_backend.d.deinit(&m_backend.d); m_gl->doneCurrent(); m_gl->context()->moveToThread(m_gl->thread()); - m_messagePainter->clearMessage(); - delete m_messagePainter; - m_messagePainter = nullptr; moveToThread(m_gl->thread()); } @@ -243,9 +234,7 @@ void PainterGL::performDraw() { m_backend.d.resized(&m_backend.d, m_size.width() * r, m_size.height() * r); m_backend.d.drawFrame(&m_backend.d); m_painter.endNativePainting(); - m_messagePainter->paint(&m_painter); -} - -void PainterGL::showMessage(const QString& message) { - m_messagePainter->showMessage(message); + if (m_messagePainter) { + m_messagePainter->paint(&m_painter); + } } diff --git a/src/platform/qt/DisplayGL.h b/src/platform/qt/DisplayGL.h index 16c7a1d0c..c49bab16c 100644 --- a/src/platform/qt/DisplayGL.h +++ b/src/platform/qt/DisplayGL.h @@ -8,8 +8,6 @@ #include "Display.h" -#include "MessagePainter.h" - #include #include #include @@ -49,8 +47,6 @@ public slots: void filter(bool filter) override; void framePosted(const uint32_t*) override; - void showMessage(const QString& message) override; - protected: virtual void paintEvent(QPaintEvent*) override {} virtual void resizeEvent(QResizeEvent*) override; @@ -62,8 +58,6 @@ private: PainterGL* m_painter; QThread* m_drawThread; GBAThread* m_context; - bool m_lockAspectRatio; - bool m_filter; }; class PainterGL : public QObject { @@ -73,6 +67,7 @@ public: PainterGL(QGLWidget* parent); void setContext(GBAThread*); + void setMessagePainter(MessagePainter*); public slots: void setBacking(const uint32_t*); @@ -86,8 +81,6 @@ public slots: void lockAspectRatio(bool lock); void filter(bool filter); - void showMessage(const QString& message); - private: void performDraw(); diff --git a/src/platform/qt/DisplayQt.cpp b/src/platform/qt/DisplayQt.cpp index 4ebcee38a..182ecd2bc 100644 --- a/src/platform/qt/DisplayQt.cpp +++ b/src/platform/qt/DisplayQt.cpp @@ -16,8 +16,6 @@ using namespace QGBA; DisplayQt::DisplayQt(QWidget* parent) : Display(parent) , m_backing(nullptr) - , m_lockAspectRatio(false) - , m_filter(false) { } @@ -25,12 +23,12 @@ void DisplayQt::startDrawing(GBAThread*) { } void DisplayQt::lockAspectRatio(bool lock) { - m_lockAspectRatio = lock; + Display::lockAspectRatio(lock); update(); } void DisplayQt::filter(bool filter) { - m_filter = filter; + Display::filter(filter); update(); } @@ -50,19 +48,15 @@ void DisplayQt::framePosted(const uint32_t* buffer) { #endif } -void DisplayQt::showMessage(const QString& message) { - m_messagePainter.showMessage(message); -} - void DisplayQt::paintEvent(QPaintEvent*) { QPainter painter(this); painter.fillRect(QRect(QPoint(), size()), Qt::black); - if (m_filter) { + if (isFiltered()) { painter.setRenderHint(QPainter::SmoothPixmapTransform); } QSize s = size(); QSize ds = s; - if (m_lockAspectRatio) { + if (isAspectRatioLocked()) { if (s.width() * 2 > s.height() * 3) { ds.setWidth(s.height() * 3 / 2); } else if (s.width() * 2 < s.height() * 3) { @@ -77,9 +71,5 @@ void DisplayQt::paintEvent(QPaintEvent*) { #else painter.drawImage(full, m_backing.rgbSwapped(), QRect(0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS)); #endif - m_messagePainter.paint(&painter); -} - -void DisplayQt::resizeEvent(QResizeEvent*) { - m_messagePainter.resize(size(), m_lockAspectRatio); + messagePainter()->paint(&painter); } diff --git a/src/platform/qt/DisplayQt.h b/src/platform/qt/DisplayQt.h index e10b13b08..f7fefb0ee 100644 --- a/src/platform/qt/DisplayQt.h +++ b/src/platform/qt/DisplayQt.h @@ -7,7 +7,6 @@ #define QGBA_DISPLAY_QT #include "Display.h" -#include "MessagePainter.h" #include #include @@ -32,17 +31,11 @@ public slots: void filter(bool filter) override; void framePosted(const uint32_t*) override; - void showMessage(const QString& message) override; - protected: virtual void paintEvent(QPaintEvent*) override; - virtual void resizeEvent(QResizeEvent*) override;; private: QImage m_backing; - bool m_lockAspectRatio; - bool m_filter; - MessagePainter m_messagePainter; }; } diff --git a/src/platform/qt/MessagePainter.cpp b/src/platform/qt/MessagePainter.cpp index a06fd0f77..49d32691f 100644 --- a/src/platform/qt/MessagePainter.cpp +++ b/src/platform/qt/MessagePainter.cpp @@ -42,7 +42,9 @@ void MessagePainter::resize(const QSize& size, bool lockAspectRatio) { m_world.reset(); m_world.translate((w - drawW) / 2, (h - drawH) / 2); m_world.scale(qreal(drawW) / VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / VIDEO_VERTICAL_PIXELS); + m_mutex.lock(); m_message.prepare(m_world, m_messageFont); + m_mutex.unlock(); } void MessagePainter::paint(QPainter* painter) { @@ -51,6 +53,7 @@ void MessagePainter::paint(QPainter* painter) { painter->setFont(m_messageFont); painter->setPen(Qt::black); painter->translate(1, VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1); + m_mutex.lock(); const static int ITERATIONS = 11; for (int i = 0; i < ITERATIONS; ++i) { painter->save(); @@ -60,11 +63,14 @@ void MessagePainter::paint(QPainter* painter) { } painter->setPen(Qt::white); painter->drawStaticText(0, 0, m_message); + m_mutex.unlock(); } void MessagePainter::showMessage(const QString& message) { + m_mutex.lock(); m_message.setText(message); m_message.prepare(m_world, m_messageFont); + m_mutex.unlock(); m_messageTimer.stop(); m_messageTimer.start(); } diff --git a/src/platform/qt/MessagePainter.h b/src/platform/qt/MessagePainter.h index d0be66bbd..a8977cb85 100644 --- a/src/platform/qt/MessagePainter.h +++ b/src/platform/qt/MessagePainter.h @@ -6,6 +6,7 @@ #ifndef QGBA_MESSAGE_PAINTER #define QGBA_MESSAGE_PAINTER +#include #include #include #include @@ -26,6 +27,7 @@ public slots: void clearMessage(); private: + QMutex m_mutex; QStaticText m_message; QTimer m_messageTimer; QTransform m_world;