cabana: use QStaticText to boost rending performance (#29900)

use QStaticText to boost rending performance
old-commit-hash: 82452ec66b
test-msgs
Dean Lee 2 years ago committed by GitHub
parent 370d912053
commit a1cb457f20
  1. 17
      tools/cabana/binaryview.cc
  2. 6
      tools/cabana/binaryview.h
  3. 7
      tools/cabana/util.cc
  4. 8
      tools/cabana/util.h

@ -280,7 +280,7 @@ void BinaryViewModel::refresh() {
updateState(); updateState();
} }
void BinaryViewModel::updateItem(int row, int col, const QString &val, const QColor &color) { void BinaryViewModel::updateItem(int row, int col, uint8_t val, const QColor &color) {
auto &item = items[row * column_count + col]; auto &item = items[row * column_count + col];
if (item.val != val || item.bg_color != color) { if (item.val != val || item.bg_color != color) {
item.val = val; item.val = val;
@ -307,7 +307,7 @@ void BinaryViewModel::updateState() {
for (int i = 0; i < binary.size(); ++i) { for (int i = 0; i < binary.size(); ++i) {
for (int j = 0; j < 8; ++j) { for (int j = 0; j < 8; ++j) {
auto &item = items[i * column_count + j]; auto &item = items[i * column_count + j];
QString val = ((binary[i] >> (7 - j)) & 1) != 0 ? "1" : "0"; int val = ((binary[i] >> (7 - j)) & 1) != 0 ? 1 : 0;
// Bit update frequency based highlighting // Bit update frequency based highlighting
double offset = !item.sigs.empty() ? 50 : 0; double offset = !item.sigs.empty() ? 50 : 0;
auto n = last_msg.bit_change_counts[i][7 - j]; auto n = last_msg.bit_change_counts[i][7 - j];
@ -317,7 +317,7 @@ void BinaryViewModel::updateState() {
color.setAlpha(alpha); color.setAlpha(alpha);
updateItem(i, j, val, color); updateItem(i, j, val, color);
} }
updateItem(i, 8, toHex(binary[i]), last_msg.colors[i]); updateItem(i, 8, binary[i], last_msg.colors[i]);
} }
} }
@ -348,6 +348,13 @@ BinaryItemDelegate::BinaryItemDelegate(QObject *parent) : QStyledItemDelegate(pa
small_font.setPixelSize(8); small_font.setPixelSize(8);
hex_font = QFontDatabase::systemFont(QFontDatabase::FixedFont); hex_font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
hex_font.setBold(true); hex_font.setBold(true);
bin_text_table[0].setText("0");
bin_text_table[1].setText("1");
for (int i = 0; i < 256; ++i) {
hex_text_table[i].setText(QStringLiteral("%1").arg(i, 2, 16, QLatin1Char('0')).toUpper());
hex_text_table[i].prepare({}, hex_font);
}
} }
bool BinaryItemDelegate::hasSignal(const QModelIndex &index, int dx, int dy, const cabana::Signal *sig) const { bool BinaryItemDelegate::hasSignal(const QModelIndex &index, int dx, int dy, const cabana::Signal *sig) const {
@ -392,7 +399,9 @@ void BinaryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
} else if (!item->valid) { } else if (!item->valid) {
painter->fillRect(option.rect, QBrush(Qt::darkGray, Qt::BDiagPattern)); painter->fillRect(option.rect, QBrush(Qt::darkGray, Qt::BDiagPattern));
} }
painter->drawText(option.rect, Qt::AlignCenter, item->val); if (item->valid) {
utils::drawStaticText(painter, option.rect, index.column() == 8 ? hex_text_table[item->val] : bin_text_table[item->val]);
}
if (item->is_msb || item->is_lsb) { if (item->is_msb || item->is_lsb) {
painter->setFont(small_font); painter->setFont(small_font);
painter->drawText(option.rect.adjusted(8, 0, -8, -3), Qt::AlignRight | Qt::AlignBottom, item->is_msb ? "M" : "L"); painter->drawText(option.rect.adjusted(8, 0, -8, -3), Qt::AlignRight | Qt::AlignBottom, item->is_msb ? "M" : "L");

@ -19,6 +19,8 @@ public:
void drawSignalCell(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index, const cabana::Signal *sig) const; void drawSignalCell(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex &index, const cabana::Signal *sig) const;
QFont small_font, hex_font; QFont small_font, hex_font;
std::array<QStaticText, 256> hex_text_table;
std::array<QStaticText, 2> bin_text_table;
}; };
class BinaryViewModel : public QAbstractTableModel { class BinaryViewModel : public QAbstractTableModel {
@ -26,7 +28,7 @@ public:
BinaryViewModel(QObject *parent) : QAbstractTableModel(parent) {} BinaryViewModel(QObject *parent) : QAbstractTableModel(parent) {}
void refresh(); void refresh();
void updateState(); void updateState();
void updateItem(int row, int col, const QString &val, const QColor &color); void updateItem(int row, int col, uint8_t val, const QColor &color);
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override { return row_count; } int rowCount(const QModelIndex &parent = QModelIndex()) const override { return row_count; }
@ -42,7 +44,7 @@ public:
QColor bg_color = QColor(102, 86, 169, 255); QColor bg_color = QColor(102, 86, 169, 255);
bool is_msb = false; bool is_msb = false;
bool is_lsb = false; bool is_lsb = false;
QString val; uint8_t val;
QList<const cabana::Signal *> sigs; QList<const cabana::Signal *> sigs;
bool valid = false; bool valid = false;
}; };

@ -1,7 +1,6 @@
#include "tools/cabana/util.h" #include "tools/cabana/util.h"
#include <algorithm> #include <algorithm>
#include <array>
#include <csignal> #include <csignal>
#include <limits> #include <limits>
#include <memory> #include <memory>
@ -56,6 +55,10 @@ std::pair<double, double> SegmentTree::get_minmax(int n, int left, int right, in
MessageBytesDelegate::MessageBytesDelegate(QObject *parent, bool multiple_lines) : multiple_lines(multiple_lines), QStyledItemDelegate(parent) { MessageBytesDelegate::MessageBytesDelegate(QObject *parent, bool multiple_lines) : multiple_lines(multiple_lines), QStyledItemDelegate(parent) {
fixed_font = QFontDatabase::systemFont(QFontDatabase::FixedFont); fixed_font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
byte_size = QFontMetrics(fixed_font).size(Qt::TextSingleLine, "00 ") + QSize(0, 2); byte_size = QFontMetrics(fixed_font).size(Qt::TextSingleLine, "00 ") + QSize(0, 2);
for (int i = 0; i < 256; ++i) {
hex_text_table[i].setText(QStringLiteral("%1").arg(i, 2, 16, QLatin1Char('0')).toUpper());
hex_text_table[i].prepare({}, fixed_font);
}
} }
int MessageBytesDelegate::widthForBytes(int n) const { int MessageBytesDelegate::widthForBytes(int n) const {
@ -107,7 +110,7 @@ void MessageBytesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
} else if (option.state & QStyle::State_Selected) { } else if (option.state & QStyle::State_Selected) {
painter->setPen(option.palette.color(QPalette::HighlightedText)); painter->setPen(option.palette.color(QPalette::HighlightedText));
} }
painter->drawText(r, Qt::AlignCenter, toHex(byte_list[i])); utils::drawStaticText(painter, r, hex_text_table[(uint8_t)(byte_list[i])]);
} }
painter->setFont(old_font); painter->setFont(old_font);
painter->setPen(old_pen); painter->setPen(old_pen);

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <array>
#include <cmath> #include <cmath>
#include <deque> #include <deque>
#include <vector> #include <vector>
@ -10,8 +11,10 @@
#include <QDateTime> #include <QDateTime>
#include <QDoubleValidator> #include <QDoubleValidator>
#include <QFont> #include <QFont>
#include <QPainter>
#include <QRegExpValidator> #include <QRegExpValidator>
#include <QSocketNotifier> #include <QSocketNotifier>
#include <QStaticText>
#include <QStringBuilder> #include <QStringBuilder>
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QToolButton> #include <QToolButton>
@ -75,6 +78,7 @@ public:
int widthForBytes(int n) const; int widthForBytes(int n) const;
private: private:
std::array<QStaticText, 256> hex_text_table;
QFont fixed_font; QFont fixed_font;
QSize byte_size = {}; QSize byte_size = {};
bool multiple_lines = false; bool multiple_lines = false;
@ -102,6 +106,10 @@ void setTheme(int theme);
inline QString formatSeconds(int seconds) { inline QString formatSeconds(int seconds) {
return QDateTime::fromSecsSinceEpoch(seconds, Qt::UTC).toString(seconds > 60 * 60 ? "hh:mm:ss" : "mm:ss"); return QDateTime::fromSecsSinceEpoch(seconds, Qt::UTC).toString(seconds > 60 * 60 ? "hh:mm:ss" : "mm:ss");
} }
inline void drawStaticText(QPainter *p, const QRect &r, const QStaticText &text) {
auto size = (r.size() - text.size()) / 2;
p->drawStaticText(r.left() + size.width(), r.top() + size.height(), text);
}
} }
class ToolButton : public QToolButton { class ToolButton : public QToolButton {

Loading…
Cancel
Save