Qt: Pre-render messages for improved speed
Jeffrey Pfau jeffrey@endrift.com
Thu, 02 Jul 2015 23:19:29 -0700
4 files changed,
53 insertions(+),
20 deletions(-)
M
src/platform/qt/Display.cpp
→
src/platform/qt/Display.cpp
@@ -52,12 +52,12 @@ setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
} 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) {
M
src/platform/qt/DisplayGL.cpp
→
src/platform/qt/DisplayGL.cpp
@@ -47,6 +47,7 @@ GBASyncSetVideoSync(&m_context->sync, false);
lockAspectRatio(isAspectRatioLocked()); filter(isFiltered()); + messagePainter()->resize(size(), isAspectRatioLocked(), devicePixelRatio()); resizePainter(); }
M
src/platform/qt/MessagePainter.cpp
→
src/platform/qt/MessagePainter.cpp
@@ -7,6 +7,8 @@ #include "MessagePainter.h"
#include <QPainter> +#include <QDebug> + extern "C" { #include "gba/video.h" }@@ -16,6 +18,7 @@
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 @@
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 @@ drawH = w * 2 / 3;
} } 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(); }
M
src/platform/qt/MessagePainter.h
→
src/platform/qt/MessagePainter.h
@@ -8,6 +8,7 @@ #define QGBA_MESSAGE_PAINTER
#include <QMutex> #include <QObject> +#include <QPixmap> #include <QStaticText> #include <QTimer>@@ -19,19 +20,26 @@
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; }; }