mirror of https://github.com/mgba-emu/mgba.git
Qt: Pre-render messages for improved speed
This commit is contained in:
parent
7395d47a5a
commit
5b3fd879b4
|
@ -52,12 +52,12 @@ Display::Display(QWidget* parent)
|
|||
}
|
||||
|
||||
void Display::resizeEvent(QResizeEvent*) {
|
||||
m_messagePainter.resize(size(), m_lockAspectRatio);
|
||||
m_messagePainter.resize(size(), m_lockAspectRatio, devicePixelRatio());
|
||||
}
|
||||
|
||||
void Display::lockAspectRatio(bool lock) {
|
||||
m_lockAspectRatio = lock;
|
||||
m_messagePainter.resize(size(), m_lockAspectRatio);
|
||||
m_messagePainter.resize(size(), m_lockAspectRatio, devicePixelRatio());
|
||||
}
|
||||
|
||||
void Display::filter(bool filter) {
|
||||
|
|
|
@ -47,6 +47,7 @@ void DisplayGL::startDrawing(GBAThread* thread) {
|
|||
|
||||
lockAspectRatio(isAspectRatioLocked());
|
||||
filter(isFiltered());
|
||||
messagePainter()->resize(size(), isAspectRatioLocked(), devicePixelRatio());
|
||||
resizePainter();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include <QPainter>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
extern "C" {
|
||||
#include "gba/video.h"
|
||||
}
|
||||
|
@ -16,6 +18,7 @@ using namespace QGBA;
|
|||
MessagePainter::MessagePainter(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_messageTimer(this)
|
||||
, m_scaleFactor(1)
|
||||
{
|
||||
m_messageFont.setFamily("Source Code Pro");
|
||||
m_messageFont.setStyleHint(QFont::Monospace);
|
||||
|
@ -27,7 +30,7 @@ MessagePainter::MessagePainter(QObject* parent)
|
|||
clearMessage();
|
||||
}
|
||||
|
||||
void MessagePainter::resize(const QSize& size, bool lockAspectRatio) {
|
||||
void MessagePainter::resize(const QSize& size, bool lockAspectRatio, qreal scaleFactor) {
|
||||
int w = size.width();
|
||||
int h = size.height();
|
||||
int drawW = w;
|
||||
|
@ -40,42 +43,63 @@ 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_scaleFactor = scaleFactor;
|
||||
m_local = QPoint(1, VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1);
|
||||
m_local = m_world.map(m_local);
|
||||
m_local += QPoint((w - drawW) / 2, (h - drawH) / 2);
|
||||
m_pixmapBuffer = QPixmap(drawW * m_scaleFactor,
|
||||
(m_messageFont.pixelSize() + 2) * m_world.m22() * m_scaleFactor);
|
||||
m_pixmapBuffer.setDevicePixelRatio(m_scaleFactor);
|
||||
m_mutex.lock();
|
||||
m_message.prepare(m_world, m_messageFont);
|
||||
redraw();
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
void MessagePainter::paint(QPainter* painter) {
|
||||
painter->setWorldTransform(m_world);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setFont(m_messageFont);
|
||||
painter->setPen(Qt::black);
|
||||
painter->translate(1, VIDEO_VERTICAL_PIXELS - m_messageFont.pixelSize() - 1);
|
||||
m_mutex.lock();
|
||||
void MessagePainter::redraw() {
|
||||
m_pixmapBuffer.fill(Qt::transparent);
|
||||
if (m_message.text().isEmpty()) {
|
||||
m_pixmap = m_pixmapBuffer;
|
||||
m_pixmap.setDevicePixelRatio(m_scaleFactor);
|
||||
return;
|
||||
}
|
||||
QPainter painter(&m_pixmapBuffer);
|
||||
painter.setWorldTransform(m_world);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setFont(m_messageFont);
|
||||
painter.setPen(Qt::black);
|
||||
const static int ITERATIONS = 11;
|
||||
for (int i = 0; i < ITERATIONS; ++i) {
|
||||
painter->save();
|
||||
painter->translate(cos(i * 2.0 * M_PI / ITERATIONS) * 0.8, sin(i * 2.0 * M_PI / ITERATIONS) * 0.8);
|
||||
painter->drawStaticText(0, 0, m_message);
|
||||
painter->restore();
|
||||
painter.save();
|
||||
painter.translate(cos(i * 2.0 * M_PI / ITERATIONS) * 0.8, sin(i * 2.0 * M_PI / ITERATIONS) * 0.8);
|
||||
painter.drawStaticText(0, 0, m_message);
|
||||
painter.restore();
|
||||
}
|
||||
painter->setPen(Qt::white);
|
||||
painter->drawStaticText(0, 0, m_message);
|
||||
m_mutex.unlock();
|
||||
painter.setPen(Qt::white);
|
||||
painter.drawStaticText(0, 0, m_message);
|
||||
m_pixmap = m_pixmapBuffer;
|
||||
m_pixmap.setDevicePixelRatio(m_scaleFactor);
|
||||
}
|
||||
|
||||
void MessagePainter::paint(QPainter* painter) {
|
||||
painter->drawPixmap(m_local, m_pixmap);
|
||||
}
|
||||
|
||||
|
||||
void MessagePainter::showMessage(const QString& message) {
|
||||
m_mutex.lock();
|
||||
m_message.setText(message);
|
||||
m_message.prepare(m_world, m_messageFont);
|
||||
redraw();
|
||||
m_mutex.unlock();
|
||||
m_messageTimer.stop();
|
||||
m_messageTimer.start();
|
||||
}
|
||||
|
||||
void MessagePainter::clearMessage() {
|
||||
m_mutex.lock();
|
||||
m_message.setText(QString());
|
||||
redraw();
|
||||
m_mutex.unlock();
|
||||
m_messageTimer.stop();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <QMutex>
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
#include <QStaticText>
|
||||
#include <QTimer>
|
||||
|
||||
|
@ -19,19 +20,26 @@ Q_OBJECT
|
|||
public:
|
||||
MessagePainter(QObject* parent = nullptr);
|
||||
|
||||
void resize(const QSize& size, bool lockAspectRatio);
|
||||
void resize(const QSize& size, bool lockAspectRatio, qreal scaleFactor);
|
||||
void paint(QPainter* painter);
|
||||
void setScaleFactor(qreal factor);
|
||||
|
||||
public slots:
|
||||
void showMessage(const QString& message);
|
||||
void clearMessage();
|
||||
|
||||
private:
|
||||
void redraw();
|
||||
|
||||
QMutex m_mutex;
|
||||
QStaticText m_message;
|
||||
QPixmap m_pixmap;
|
||||
QPixmap m_pixmapBuffer;
|
||||
QTimer m_messageTimer;
|
||||
QPoint m_local;
|
||||
QTransform m_world;
|
||||
QFont m_messageFont;
|
||||
qreal m_scaleFactor;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue