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