Qt: Move message painting into Display

This commit is contained in:
Jeffrey Pfau 2015-07-02 22:17:06 -07:00
parent 7c629a76ba
commit 7395d47a5a
8 changed files with 62 additions and 58 deletions

View File

@ -50,3 +50,20 @@ Display::Display(QWidget* parent)
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); 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);
}

View File

@ -8,6 +8,8 @@
#include <QWidget> #include <QWidget>
#include "MessagePainter.h"
struct GBAThread; struct GBAThread;
namespace QGBA { namespace QGBA {
@ -28,20 +30,32 @@ public:
static Display* create(QWidget* parent = nullptr); static Display* create(QWidget* parent = nullptr);
static void setDriver(Driver driver) { s_driver = driver; } static void setDriver(Driver driver) { s_driver = driver; }
bool isAspectRatioLocked() const { return m_lockAspectRatio; }
bool isFiltered() const { return m_filter; }
public slots: public slots:
virtual void startDrawing(GBAThread* context) = 0; virtual void startDrawing(GBAThread* context) = 0;
virtual void stopDrawing() = 0; virtual void stopDrawing() = 0;
virtual void pauseDrawing() = 0; virtual void pauseDrawing() = 0;
virtual void unpauseDrawing() = 0; virtual void unpauseDrawing() = 0;
virtual void forceDraw() = 0; virtual void forceDraw() = 0;
virtual void lockAspectRatio(bool lock) = 0; virtual void lockAspectRatio(bool lock);
virtual void filter(bool filter) = 0; virtual void filter(bool filter);
virtual void framePosted(const uint32_t*) = 0; 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: private:
static Driver s_driver; static Driver s_driver;
MessagePainter m_messagePainter;
bool m_lockAspectRatio;
bool m_filter;
}; };
} }

View File

@ -19,8 +19,6 @@ DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent)
, m_gl(new EmptyGLWidget(format, this)) , m_gl(new EmptyGLWidget(format, this))
, m_painter(new PainterGL(m_gl)) , m_painter(new PainterGL(m_gl))
, m_drawThread(nullptr) , m_drawThread(nullptr)
, m_lockAspectRatio(false)
, m_filter(false)
, m_context(nullptr) , m_context(nullptr)
{ {
} }
@ -34,6 +32,7 @@ void DisplayGL::startDrawing(GBAThread* thread) {
return; return;
} }
m_painter->setContext(thread); m_painter->setContext(thread);
m_painter->setMessagePainter(messagePainter());
m_context = thread; m_context = thread;
m_painter->resize(size()); m_painter->resize(size());
m_gl->move(0, 0); m_gl->move(0, 0);
@ -46,8 +45,8 @@ void DisplayGL::startDrawing(GBAThread* thread) {
m_drawThread->start(); m_drawThread->start();
GBASyncSetVideoSync(&m_context->sync, false); GBASyncSetVideoSync(&m_context->sync, false);
lockAspectRatio(m_lockAspectRatio); lockAspectRatio(isAspectRatioLocked());
filter(m_filter); filter(isFiltered());
resizePainter(); resizePainter();
} }
@ -96,14 +95,14 @@ void DisplayGL::forceDraw() {
} }
void DisplayGL::lockAspectRatio(bool lock) { void DisplayGL::lockAspectRatio(bool lock) {
m_lockAspectRatio = lock; Display::lockAspectRatio(lock);
if (m_drawThread) { if (m_drawThread) {
QMetaObject::invokeMethod(m_painter, "lockAspectRatio", Q_ARG(bool, lock)); QMetaObject::invokeMethod(m_painter, "lockAspectRatio", Q_ARG(bool, lock));
} }
} }
void DisplayGL::filter(bool filter) { void DisplayGL::filter(bool filter) {
m_filter = filter; Display::filter(filter);
if (m_drawThread) { if (m_drawThread) {
QMetaObject::invokeMethod(m_painter, "filter", Q_ARG(bool, filter)); 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) { void DisplayGL::resizeEvent(QResizeEvent* event) {
if (m_drawThread) { Display::resizeEvent(event);
QMetaObject::invokeMethod(m_painter, "showMessage", Qt::BlockingQueuedConnection, Q_ARG(const QString&, message));
}
}
void DisplayGL::resizeEvent(QResizeEvent*) {
resizePainter(); resizePainter();
} }
@ -152,6 +146,10 @@ void PainterGL::setContext(GBAThread* context) {
m_context = context; m_context = context;
} }
void PainterGL::setMessagePainter(MessagePainter* messagePainter) {
m_messagePainter = messagePainter;
}
void PainterGL::setBacking(const uint32_t* backing) { void PainterGL::setBacking(const uint32_t* backing) {
m_gl->makeCurrent(); m_gl->makeCurrent();
m_backend.d.postFrame(&m_backend.d, backing); 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) { void PainterGL::resize(const QSize& size) {
m_size = size; m_size = size;
if (m_active) { if (m_active) {
m_messagePainter->resize(size, m_backend.d.lockAspectRatio);
forceDraw(); forceDraw();
} }
} }
@ -172,7 +169,6 @@ void PainterGL::resize(const QSize& size) {
void PainterGL::lockAspectRatio(bool lock) { void PainterGL::lockAspectRatio(bool lock) {
m_backend.d.lockAspectRatio = lock; m_backend.d.lockAspectRatio = lock;
if (m_active) { if (m_active) {
m_messagePainter->resize(m_size, m_backend.d.lockAspectRatio);
forceDraw(); forceDraw();
} }
} }
@ -185,8 +181,6 @@ void PainterGL::filter(bool filter) {
} }
void PainterGL::start() { void PainterGL::start() {
m_messagePainter = new MessagePainter(this);
m_messagePainter->resize(m_size, m_backend.d.lockAspectRatio);
m_gl->makeCurrent(); m_gl->makeCurrent();
m_backend.d.init(&m_backend.d, reinterpret_cast<WHandle>(m_gl->winId())); m_backend.d.init(&m_backend.d, reinterpret_cast<WHandle>(m_gl->winId()));
m_gl->doneCurrent(); m_gl->doneCurrent();
@ -220,9 +214,6 @@ void PainterGL::stop() {
m_backend.d.deinit(&m_backend.d); m_backend.d.deinit(&m_backend.d);
m_gl->doneCurrent(); m_gl->doneCurrent();
m_gl->context()->moveToThread(m_gl->thread()); m_gl->context()->moveToThread(m_gl->thread());
m_messagePainter->clearMessage();
delete m_messagePainter;
m_messagePainter = nullptr;
moveToThread(m_gl->thread()); 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.resized(&m_backend.d, m_size.width() * r, m_size.height() * r);
m_backend.d.drawFrame(&m_backend.d); m_backend.d.drawFrame(&m_backend.d);
m_painter.endNativePainting(); m_painter.endNativePainting();
if (m_messagePainter) {
m_messagePainter->paint(&m_painter); m_messagePainter->paint(&m_painter);
} }
void PainterGL::showMessage(const QString& message) {
m_messagePainter->showMessage(message);
} }

View File

@ -8,8 +8,6 @@
#include "Display.h" #include "Display.h"
#include "MessagePainter.h"
#include <QGLWidget> #include <QGLWidget>
#include <QThread> #include <QThread>
#include <QTimer> #include <QTimer>
@ -49,8 +47,6 @@ public slots:
void filter(bool filter) override; void filter(bool filter) override;
void framePosted(const uint32_t*) override; void framePosted(const uint32_t*) override;
void showMessage(const QString& message) override;
protected: protected:
virtual void paintEvent(QPaintEvent*) override {} virtual void paintEvent(QPaintEvent*) override {}
virtual void resizeEvent(QResizeEvent*) override; virtual void resizeEvent(QResizeEvent*) override;
@ -62,8 +58,6 @@ private:
PainterGL* m_painter; PainterGL* m_painter;
QThread* m_drawThread; QThread* m_drawThread;
GBAThread* m_context; GBAThread* m_context;
bool m_lockAspectRatio;
bool m_filter;
}; };
class PainterGL : public QObject { class PainterGL : public QObject {
@ -73,6 +67,7 @@ public:
PainterGL(QGLWidget* parent); PainterGL(QGLWidget* parent);
void setContext(GBAThread*); void setContext(GBAThread*);
void setMessagePainter(MessagePainter*);
public slots: public slots:
void setBacking(const uint32_t*); void setBacking(const uint32_t*);
@ -86,8 +81,6 @@ public slots:
void lockAspectRatio(bool lock); void lockAspectRatio(bool lock);
void filter(bool filter); void filter(bool filter);
void showMessage(const QString& message);
private: private:
void performDraw(); void performDraw();

View File

@ -16,8 +16,6 @@ using namespace QGBA;
DisplayQt::DisplayQt(QWidget* parent) DisplayQt::DisplayQt(QWidget* parent)
: Display(parent) : Display(parent)
, m_backing(nullptr) , m_backing(nullptr)
, m_lockAspectRatio(false)
, m_filter(false)
{ {
} }
@ -25,12 +23,12 @@ void DisplayQt::startDrawing(GBAThread*) {
} }
void DisplayQt::lockAspectRatio(bool lock) { void DisplayQt::lockAspectRatio(bool lock) {
m_lockAspectRatio = lock; Display::lockAspectRatio(lock);
update(); update();
} }
void DisplayQt::filter(bool filter) { void DisplayQt::filter(bool filter) {
m_filter = filter; Display::filter(filter);
update(); update();
} }
@ -50,19 +48,15 @@ void DisplayQt::framePosted(const uint32_t* buffer) {
#endif #endif
} }
void DisplayQt::showMessage(const QString& message) {
m_messagePainter.showMessage(message);
}
void DisplayQt::paintEvent(QPaintEvent*) { void DisplayQt::paintEvent(QPaintEvent*) {
QPainter painter(this); QPainter painter(this);
painter.fillRect(QRect(QPoint(), size()), Qt::black); painter.fillRect(QRect(QPoint(), size()), Qt::black);
if (m_filter) { if (isFiltered()) {
painter.setRenderHint(QPainter::SmoothPixmapTransform); painter.setRenderHint(QPainter::SmoothPixmapTransform);
} }
QSize s = size(); QSize s = size();
QSize ds = s; QSize ds = s;
if (m_lockAspectRatio) { if (isAspectRatioLocked()) {
if (s.width() * 2 > s.height() * 3) { if (s.width() * 2 > s.height() * 3) {
ds.setWidth(s.height() * 3 / 2); ds.setWidth(s.height() * 3 / 2);
} else if (s.width() * 2 < s.height() * 3) { } else if (s.width() * 2 < s.height() * 3) {
@ -77,9 +71,5 @@ void DisplayQt::paintEvent(QPaintEvent*) {
#else #else
painter.drawImage(full, m_backing.rgbSwapped(), QRect(0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS)); painter.drawImage(full, m_backing.rgbSwapped(), QRect(0, 0, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS));
#endif #endif
m_messagePainter.paint(&painter); messagePainter()->paint(&painter);
}
void DisplayQt::resizeEvent(QResizeEvent*) {
m_messagePainter.resize(size(), m_lockAspectRatio);
} }

View File

@ -7,7 +7,6 @@
#define QGBA_DISPLAY_QT #define QGBA_DISPLAY_QT
#include "Display.h" #include "Display.h"
#include "MessagePainter.h"
#include <QImage> #include <QImage>
#include <QTimer> #include <QTimer>
@ -32,17 +31,11 @@ public slots:
void filter(bool filter) override; void filter(bool filter) override;
void framePosted(const uint32_t*) override; void framePosted(const uint32_t*) override;
void showMessage(const QString& message) override;
protected: protected:
virtual void paintEvent(QPaintEvent*) override; virtual void paintEvent(QPaintEvent*) override;
virtual void resizeEvent(QResizeEvent*) override;;
private: private:
QImage m_backing; QImage m_backing;
bool m_lockAspectRatio;
bool m_filter;
MessagePainter m_messagePainter;
}; };
} }

View File

@ -42,7 +42,9 @@ void MessagePainter::resize(const QSize& size, bool lockAspectRatio) {
m_world.reset(); m_world.reset();
m_world.translate((w - drawW) / 2, (h - drawH) / 2); m_world.translate((w - drawW) / 2, (h - drawH) / 2);
m_world.scale(qreal(drawW) / VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / VIDEO_VERTICAL_PIXELS); m_world.scale(qreal(drawW) / VIDEO_HORIZONTAL_PIXELS, qreal(drawH) / VIDEO_VERTICAL_PIXELS);
m_mutex.lock();
m_message.prepare(m_world, m_messageFont); m_message.prepare(m_world, m_messageFont);
m_mutex.unlock();
} }
void MessagePainter::paint(QPainter* painter) { void MessagePainter::paint(QPainter* painter) {
@ -51,6 +53,7 @@ void MessagePainter::paint(QPainter* painter) {
painter->setFont(m_messageFont); painter->setFont(m_messageFont);
painter->setPen(Qt::black); painter->setPen(Qt::black);
painter->translate(1, VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1); painter->translate(1, VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1);
m_mutex.lock();
const static int ITERATIONS = 11; const static int ITERATIONS = 11;
for (int i = 0; i < ITERATIONS; ++i) { for (int i = 0; i < ITERATIONS; ++i) {
painter->save(); painter->save();
@ -60,11 +63,14 @@ void MessagePainter::paint(QPainter* painter) {
} }
painter->setPen(Qt::white); painter->setPen(Qt::white);
painter->drawStaticText(0, 0, m_message); painter->drawStaticText(0, 0, m_message);
m_mutex.unlock();
} }
void MessagePainter::showMessage(const QString& message) { void MessagePainter::showMessage(const QString& message) {
m_mutex.lock();
m_message.setText(message); m_message.setText(message);
m_message.prepare(m_world, m_messageFont); m_message.prepare(m_world, m_messageFont);
m_mutex.unlock();
m_messageTimer.stop(); m_messageTimer.stop();
m_messageTimer.start(); m_messageTimer.start();
} }

View File

@ -6,6 +6,7 @@
#ifndef QGBA_MESSAGE_PAINTER #ifndef QGBA_MESSAGE_PAINTER
#define QGBA_MESSAGE_PAINTER #define QGBA_MESSAGE_PAINTER
#include <QMutex>
#include <QObject> #include <QObject>
#include <QStaticText> #include <QStaticText>
#include <QTimer> #include <QTimer>
@ -26,6 +27,7 @@ public slots:
void clearMessage(); void clearMessage();
private: private:
QMutex m_mutex;
QStaticText m_message; QStaticText m_message;
QTimer m_messageTimer; QTimer m_messageTimer;
QTransform m_world; QTransform m_world;