Terminal: Limit updates to 30fps

Task-number: QTCREATORBUG-30135
Change-Id: Ief7b368b8d291d50c626de55f8dccebf4f43e388
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-08-28 09:39:40 +02:00
parent f95d904d0e
commit 821fd0c90a
3 changed files with 42 additions and 5 deletions

View File

@@ -281,7 +281,9 @@ struct TerminalSurfacePrivate
int sb_pushline(int cols, const VTermScreenCell *cells) int sb_pushline(int cols, const VTermScreenCell *cells)
{ {
auto oldSize = m_scrollback->size();
m_scrollback->emplace(cols, cells); m_scrollback->emplace(cols, cells);
if (m_scrollback->size() != oldSize)
emit q->fullSizeChanged(q->fullSize()); emit q->fullSizeChanged(q->fullSize());
return 1; return 1;
} }

View File

@@ -50,6 +50,9 @@ public:
m_flushDelayTimer.setSingleShot(true); m_flushDelayTimer.setSingleShot(true);
m_flushDelayTimer.setInterval(minRefreshInterval); m_flushDelayTimer.setInterval(minRefreshInterval);
m_updateTimer.setSingleShot(true);
m_updateTimer.setInterval(minRefreshInterval);
m_scrollTimer.setSingleShot(false); m_scrollTimer.setSingleShot(false);
m_scrollTimer.setInterval(500ms); m_scrollTimer.setInterval(500ms);
} }
@@ -73,6 +76,10 @@ public:
QTimer m_flushDelayTimer; QTimer m_flushDelayTimer;
QTimer m_updateTimer;
std::optional<QRegion> m_updateRegion;
QElapsedTimer m_sinceLastPaint;
QTimer m_scrollTimer; QTimer m_scrollTimer;
int m_scrollDirection{0}; int m_scrollDirection{0};
@@ -142,6 +149,7 @@ TerminalView::TerminalView(QWidget *parent)
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
connect(&d->m_flushDelayTimer, &QTimer::timeout, this, [this] { flushVTerm(true); }); connect(&d->m_flushDelayTimer, &QTimer::timeout, this, [this] { flushVTerm(true); });
connect(&d->m_updateTimer, &QTimer::timeout, this, &TerminalView::scheduleViewportUpdate);
connect(&d->m_scrollTimer, &QTimer::timeout, this, [this] { connect(&d->m_scrollTimer, &QTimer::timeout, this, [this] {
if (d->m_scrollDirection < 0) if (d->m_scrollDirection < 0)
@@ -920,6 +928,8 @@ void TerminalView::paintEvent(QPaintEvent *event)
QToolTip::showText(this->mapToGlobal(QPoint(width() - 200, 0)), QToolTip::showText(this->mapToGlobal(QPoint(width() - 200, 0)),
QString("Paint: %1ms").arg(t.elapsed())); QString("Paint: %1ms").arg(t.elapsed()));
} }
d->m_sinceLastPaint.start();
} }
void TerminalView::keyPressEvent(QKeyEvent *event) void TerminalView::keyPressEvent(QKeyEvent *event)
@@ -1018,17 +1028,39 @@ QPoint TerminalView::toGridPos(QMouseEvent *event) const
return globalToGrid(QPointF(event->pos()) + QPointF(0, -topMargin() + 0.5)); return globalToGrid(QPointF(event->pos()) + QPointF(0, -topMargin() + 0.5));
} }
void TerminalView::scheduleViewportUpdate()
{
if (!d->m_passwordModeActive && d->m_updateRegion)
viewport()->update(*d->m_updateRegion);
else
viewport()->update();
d->m_updateRegion.reset();
}
void TerminalView::updateViewport() void TerminalView::updateViewport()
{ {
viewport()->update(); updateViewportRect({});
} }
void TerminalView::updateViewportRect(const QRect &rect) void TerminalView::updateViewportRect(const QRect &rect)
{ {
if (d->m_passwordModeActive) if (rect.isEmpty())
viewport()->update(); d->m_updateRegion = QRegion{viewport()->rect()};
else if (!d->m_updateRegion)
d->m_updateRegion = QRegion(rect);
else else
viewport()->update(rect); d->m_updateRegion = d->m_updateRegion->united(rect);
if (d->m_updateTimer.isActive())
return;
if (d->m_sinceLastPaint.durationElapsed() < minRefreshInterval) {
d->m_updateTimer.start();
return;
}
scheduleViewportUpdate();
} }
void TerminalView::focusInEvent(QFocusEvent *) void TerminalView::focusInEvent(QFocusEvent *)

View File

@@ -221,6 +221,9 @@ protected:
QColor toQColor(std::variant<int, QColor> color) const; QColor toQColor(std::variant<int, QColor> color) const;
private:
void scheduleViewportUpdate();
private: private:
std::unique_ptr<TerminalViewPrivate> d; std::unique_ptr<TerminalViewPrivate> d;
}; };