From b721d9847664971a14995c280d08577cb3c0cb86 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 30 Jun 2023 10:37:53 +0200 Subject: [PATCH] Editor: optimize annotation cache cleanup Looking up the last visible block is not for free since it calculates the bounding rects for all blocks between the first and last visible block. Avoid one calculation by postponing the annotation cleanup after the paint event and only if we reach a certain amount of cached entries. Change-Id: Ibfab49301f82237e16d5a69ce1531539907e7ed8 Reviewed-by: hjk --- src/plugins/texteditor/texteditor.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index e6160b3e547..ac0d3ebee42 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -449,6 +449,7 @@ struct PaintEventData , textCursorBlock(textCursor.block()) , isEditable(!editor->isReadOnly()) , fontSettings(editor->textDocument()->fontSettings()) + , lineSpacing(fontSettings.lineSpacing()) , searchScopeFormat(fontSettings.toTextCharFormat(C_SEARCH_SCOPE)) , searchResultFormat(fontSettings.toTextCharFormat(C_SEARCH_RESULT)) , visualWhitespaceFormat(fontSettings.toTextCharFormat(C_VISUAL_WHITESPACE)) @@ -469,6 +470,7 @@ struct PaintEventData const QTextBlock textCursorBlock; const bool isEditable; const FontSettings fontSettings; + const int lineSpacing; const QTextCharFormat searchScopeFormat; const QTextCharFormat searchResultFormat; const QTextCharFormat visualWhitespaceFormat; @@ -561,6 +563,7 @@ public: QPainter &painter, const PaintEventBlockData &blockData) const; QTextBlock nextVisibleBlock(const QTextBlock &block) const; + void scheduleCleanupAnnotationCache(); void cleanupAnnotationCache(); // extra area paint methods @@ -706,6 +709,7 @@ public: friend bool operator==(const AnnotationRect &a, const AnnotationRect &b) { return a.mark == b.mark && a.rect == b.rect; } }; + bool cleanupAnnotationRectsScheduled = false; QMap> m_annotationRects; QRectF getLastLineLineRect(const QTextBlock &block); @@ -4225,6 +4229,9 @@ void TextEditorWidgetPrivate::updateLineAnnotation(const PaintEventData &data, q->viewport()->update(annotationRect.rect.toAlignedRect()); } m_annotationRects[data.block.blockNumber()] = newRects; + const int maxVisibleLines = data.viewportRect.height() / data.lineSpacing; + if (m_annotationRects.size() >= maxVisibleLines * 2) + scheduleCleanupAnnotationCache(); } QColor blendRightMarginColor(const FontSettings &settings, bool areaColor) @@ -4892,8 +4899,19 @@ QTextBlock TextEditorWidgetPrivate::nextVisibleBlock(const QTextBlock &block) co return TextEditor::nextVisibleBlock(block, q->document()); } +void TextEditorWidgetPrivate::scheduleCleanupAnnotationCache() +{ + if (cleanupAnnotationRectsScheduled) + return; + QMetaObject::invokeMethod(this, + &TextEditorWidgetPrivate::cleanupAnnotationCache, + Qt::QueuedConnection); + cleanupAnnotationRectsScheduled = true; +} + void TextEditorWidgetPrivate::cleanupAnnotationCache() { + cleanupAnnotationRectsScheduled = false; const int firstVisibleBlock = q->firstVisibleBlockNumber(); const int lastVisibleBlock = q->lastVisibleBlockNumber(); auto lineIsVisble = [&](int blockNumber){ @@ -5015,8 +5033,6 @@ void TextEditorWidget::paintEvent(QPaintEvent *e) } } - d->cleanupAnnotationCache(); - painter.setPen(data.context.palette.text().color()); d->updateAnimator(d->m_bracketsAnimator, painter);